Out-of-Core Image Classification
Train a network to distinguish the digits 1 from 2, and only load small batches of images into memory from disk at a time.
Download a set of images and unzip them.
In[1]:=
zip = URLDownload["https://wolfr.am/ebyHmnkR", "characters12.zip"];
dir = CreateDirectory[];
ExtractArchive[First @ zip, dir] // Length
Out[1]=
Obtain the image file paths and obtain the classes from the folder names.
In[2]:=
loadFiles[dir_] :=
Map[File[#] -> FileNameTake[#, {-2}] &,
FileNames["*.jpg", dir, Infinity]];
trainingData = loadFiles[FileNameJoin[{dir, "characters", "train"}]];
testData = loadFiles[FileNameJoin[{dir, "characters", "test"}]];
The training data is a list of rules from File objects to classes.
In[3]:=
RandomSample[trainingData, 3]
Out[3]=
Define a simple network.
In[4]:=
net = NetChain[
{FlattenLayer[], DotPlusLayer[2], SoftmaxLayer[]},
"Output" -> NetDecoder[{"Class", {"1", "2"}}],
"Input" -> NetEncoder[{"Image", {28, 28}, "Grayscale"}]
]
Out[4]=
Train the network.
In[5]:=
trained =
NetTrain[net, trainingData, ValidationSet -> testData,
MaxTrainingRounds -> 600, BatchSize -> 64]
Out[6]=
Classify images directly from file paths.
In[7]:=
ims = Keys@RandomSample[testData, 3]
trained /@ ims
Out[7]=
Out[7]=
Or evaluate directly on an image and obtain the classification probabilities.
In[8]:=
trained[\!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
1:eJztVUtrGlEUNj6iiY9UySJIN125zUq6kEhEIg3oIqULlwlNQ0GmqIVqRCQG
NZJV8Ee4yUbBXVYJ5Ff4A4yiece308859TBMHkwX3fVADtc7537nO8982Pmx
9U2r0WjiJqit7V/rsdh28vM7/PgixL/vCbtfPwk/d/d2Yx93dLh8/+dvehZf
kclkAv3w8CD/ORqNoB8fH9ns/v4eejAYvIYjF3pOcnV1RYfr6+vxeIwDdLfb
ZRu58RvS6/XkPPlMJPv9PpEE8s3NjRpAEqLE+KenpxsbG3q9fprkeNxoNObz
eTIAshpAhElQCLxerx8eHmokmZubgzaZppWzWq2xWEwei0oJBAKEBoZLS0s4
2O12zUxOTk5gMxwO1QM2m83FxUW8NZvNYOVyuUQpjbVaDTcGgwGfkKK7uzs1
aNQksKdIc7lcu90WZ9VBoYknMsxpVyPUkxNJ6IaTDMzNzU1gZrNZ9YB4y50M
hKenJ/6E7CWTSQAuLCxEIhHcqIxdDs5Qt7e30KANepSTYrHYaDRUQnHLKeaO
RsYoCXjCi8ohIkHyuffAls/lcplaK5VK0U2r1VIDCATFHBF5XDqdTur8v02j
KEUN5MvLy4ODg/39/ePjYxDT6XTURegu2CB2efneFvRnKBTCW61WSyBIIB0s
Fgs0eok6Fsy52eTPOS6SQqGAVzabjTYGJojQ5ufn2QWNPNZIp9N5TgleuHZI
kd/vZ3pra2ulUsnr9cqRM5kMDb5ekouLC0XpeRPiHjoYDGKKER2MBUE4Ojpa
XV3F8+XlZXjxeDzn5+coWaVSCYfD5AL3itjl2YA9L5xEIoHYcaAdgqh9Pp8i
Y7z6XiwHEcYyBB+YgSrWDoGvrKy43e5oNIoJAkMUGquegsU0pdPps7MzbjZF
MrEfkHB5/hE+qIKwggPZwwXP2vN/Hxw78oCMORwOAKL01WqVvlIHonzoWLgW
Z1MAcKC9uOsQjih1OFlSKsgRDTtpdk0ueFTJy3/5d/IbNwt7sQ==
"], {{0, 28}, {
28, 0}}, {0, 255},
ColorFunction->RGBColor],
BoxForm`ImageTag["Byte", ColorSpace -> "RGB", Interleaving -> True],
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSize->Automatic,
ImageSizeRaw->{28, 28},
PlotRange->{{0, 28}, {0, 28}}]\), "Probabilities"]
Out[8]=