{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "// %install '.package(path: \"$cwd/FastaiNotebook_03_minibatch_training\")' FastaiNotebook_03_minibatch_training\n", "%install '.package(path: \"$cwd/FastaiNotebook_04_callbacks\")' FastaiNotebook_04_callbacks" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "let IMAGENETTE_URL = \"https://s3.amazonaws.com/fast-ai-imageclas/imagenette.tgz\"\n", "let IMAGENETTE_160_URL = \"https://s3.amazonaws.com/fast-ai-imageclas/imagenette-160.tgz\"\n", "let IMAGENETTE_320_URL = \"https://s3.amazonaws.com/fast-ai-imageclas/imagenette-320.tgz\"\n", "let IMAGENETTE_FILE = \"imagenette.tgz\"\n", "\n", "// First let us download the dataset. \n", "func downloadImagenetteData(_ url: String, _ filename: String) -> String {\n", " let urllib = Python.import(\"urllib.request\")\n", " let downloadResult = urllib.urlretrieve(url, filename)\n", " print(\"\\(downloadResult[0])\")\n", " return String(downloadResult[0])!\n", "}\n", "\n", "//downloadImagenetteData(IMAGENETTE_160_URL, IMAGENETTE_FILE)\n", "subprocess.run([\"wget\", IMAGENETTE_160_URL])\n", "subprocess.run([\"tar\", \"-xzvf\", \"imagenette-160.tgz\"])\n", "subprocess.run([\"ls\"])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "// Create a list of files\n", "subprocess.run([\"find\", \"imagenette-160/train\", \"-name\", \"*.JPEG\", \"-fprint\", \"imagenette-train-files.txt\"])\n", "subprocess.run([\"find\", \"imagenette-160/val\", \"-name\", \"*.JPEG\", \"-fprint\", \"imagenette-val-files.txt\"])\n", "subprocess.run([\"ls\"])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%include \"EnableIPythonDisplay.swift\"\n", "IPythonDisplay.shell.enable_matplotlib(\"inline\")\n", "\n", "import TensorFlow\n", "import Python\n", "//import Foundation\n", "\n", "let subprocess = Python.import(\"subprocess\")\n", "let plt = Python.import(\"matplotlib.pyplot\")\n", "let np = Python.import(\"numpy\")\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/plain": [ "None\n" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// Utility to resize an image!\n", "func resizeImage(filename: StringTensor) -> Tensor {\n", " let imageBytes: StringTensor = Raw.readFile(filename: filename)\n", " let decodedImage = Raw.decodeJpeg(contents: imageBytes, channels: 3, dctMethod: \"\") \n", " let resizedImages = Raw.resizeBicubic(\n", " images: Tensor([decodedImage]), \n", " size: Tensor([32, 32]))\n", " return resizedImages.reshaped(to: TensorShape(32, 32, 3))\n", "// return Raw.cast(resizedImage)\n", "}\n", "\n", "let resizedImage = resizeImage(filename: StringTensor(\"imagenette-160/val/n03028079/ILSVRC2012_val_00003682.JPEG\"))\n", "let npa = resizedImage.makeNumpyArray().astype(np.uint8)\n", "plt.imshow(npa) \n", "plt.show()\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "// Some sample data to quickly test things!\n", "let sampleValFiles: [String] = [\n", " \"imagenette-160/val/n03028079/ILSVRC2012_val_00034021.JPEG\",\n", " \"imagenette-160/val/n03028079/ILSVRC2012_val_00026451.JPEG\",\n", " \"imagenette-160/val/n03028079/ILSVRC2012_val_00006268.JPEG\",\n", " \"imagenette-160/val/n03028079/ILSVRC2012_val_00004912.JPEG\",\n", " \"imagenette-160/val/n03028079/ILSVRC2012_val_00009705.JPEG\",\n", " \"imagenette-160/val/n03000684/ILSVRC2012_val_00000537.JPEG\",\n", " \"imagenette-160/val/n03000684/ILSVRC2012_val_00004034.JPEG\",\n", " \"imagenette-160/val/n03000684/ILSVRC2012_val_00004262.JPEG\",\n", " \"imagenette-160/val/n03000684/ILSVRC2012_val_00005506.JPEG\",\n", " \"imagenette-160/val/n03000684/ILSVRC2012_val_00006043.JPEG\",\n", " \"imagenette-160/val/n01440764/ILSVRC2012_val_00000293.JPEG\",\n", " \"imagenette-160/val/n01440764/ILSVRC2012_val_00002138.JPEG\",\n", " \"imagenette-160/val/n01440764/ILSVRC2012_val_00003014.JPEG\",\n", " \"imagenette-160/val/n01440764/ILSVRC2012_val_00006697.JPEG\",\n", " \"imagenette-160/val/n01440764/ILSVRC2012_val_00007197.JPEG\"\n", "]\n", "let sampleValFilesTensor = StringTensor(sampleValFiles)\n", "let sampleTrainFiles: [String] = [\n", " \"imagenette-160/train/n01440764/n01440764_10026.JPEG\",\n", " \"imagenette-160/train/n01440764/n01440764_10027.JPEG\",\n", " \"imagenette-160/train/n01440764/n01440764_10029.JPEG\",\n", " \"imagenette-160/train/n01440764/n01440764_10040.JPEG\",\n", " \"imagenette-160/train/n01440764/n01440764_10042.JPEG\",\n", " \"imagenette-160/train/n03000684/n03000684_1000.JPEG\",\n", " \"imagenette-160/train/n03000684/n03000684_1011.JPEG\",\n", " \"imagenette-160/train/n03000684/n03000684_10131.JPEG\",\n", " \"imagenette-160/train/n03000684/n03000684_10132.JPEG\",\n", " \"imagenette-160/train/n03000684/n03000684_10136.JPEG\",\n", " \"imagenette-160/train/n03028079/n03028079_10006.JPEG\",\n", " \"imagenette-160/train/n03028079/n03028079_10014.JPEG\",\n", " \"imagenette-160/train/n03028079/n03028079_10020.JPEG\",\n", " \"imagenette-160/train/n03028079/n03028079_1002.JPEG\",\n", " \"imagenette-160/train/n03028079/n03028079_10032.JPEG\"\n", "]\n", "let sampleTrainFilesTensor = StringTensor(sampleTrainFiles)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Processing image 0\n", "Processing image 1\n", "Processing image 2\n", "Processing image 3\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/plain": [ "None\n" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "// Test a basic dataset that reads and resizes images\n", "\n", "let ds:Dataset> = Dataset(\n", " elements: sampleTrainFilesTensor).map(resizeImage)\n", "//.batched(5) // For batching\n", "\n", "let rows = 2 \n", "let cols = 2 \n", "//plt.figure(figsize: [rows * 3, cols * 3])\n", "\n", "for (i, d) in ds.enumerated() {\n", " print(\"Processing image \\(i)\")\n", " let img = plt.subplot(rows, cols, i + 1)\n", " img.imshow(d.makeNumpyArray().astype(np.uint8))\n", " if (i + 1) >= (rows * cols) { break }\n", "}\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "// Some data structures from 03 minibatch training\n", "\n", "// export\n", "public struct DataBatch: TensorGroup {\n", " public var xb: Inputs\n", " public var yb: Labels\n", "\n", " public init(xb: Inputs, yb: Labels){\n", " self.xb = xb\n", " self.yb = yb\n", " }\n", "}\n", "\n", "// export\n", "public struct DataBunch where Element: TensorGroup{\n", " public var train: Dataset\n", " public var valid: Dataset\n", " \n", " public init(train: Dataset, valid: Dataset) {\n", " self.train = train\n", " self.valid = valid\n", " }\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Labels: TensorShape(dimensions: [15]) \r\n", " [1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 2.0, 2.0]\r\n", "Fnames: StringTensor(handle: TensorFlow.TensorHandle)\r\n" ] } ], "source": [ "// TODO: When TF-421 is fixed, switch this back to Int32 labels.\n", "\n", "struct LabeledImagenetteFiles : TensorGroup {\n", " let labels: Tensor\n", " let fnames: StringTensor\n", "}\n", "\n", "// e.g., getLabel(from: \"imagenette-160/train/n03028079/ILSVRC2012_val_00034021.JPEG\")\n", "func getLabel(from fname: String) -> String {\n", " // let splits = fname.components(separatedBy: \"/\")\n", " // let splits = fname.pathComponents\n", " let splits = fname.split(separator: \"/\")\n", " assert(splits.endIndex >= 2, \"Filename is not in the relevant form.\")\n", " return String(splits[splits.endIndex - 2])\n", "}\n", "\n", "func labeledFiles(fnames: [String]) -> LabeledImagenetteFiles {\n", " var labels: [String] = []\n", " for fname in fnames {\n", " labels.append(getLabel(from: fname))\n", " } \n", " var labelsDict: [String: Float] = [:]\n", " for (i, label) in Set(labels).enumerated() {\n", " labelsDict[label] = Float(i)\n", " }\n", " let labelIds = labels.map { labelsDict[$0]! }\n", " return LabeledImagenetteFiles(\n", " labels: Tensor(labelIds), \n", " fnames: StringTensor(fnames)\n", " )\n", "}\n", "\n", "/* TODO: Enable when we can have pre-built toolchain with Foundation\n", "\n", "func labeledFiles(from inputFile: String) -> [LabeledImagenetteInput] {\n", " do { \n", " let fileContents = try String(contentsOfFile: inputFile)\n", " let fnamesRaw = fileContents.components(separatedBy: .newlines)\n", " let fnames = fnamesRaw.filter { !$0.trimmingCharacters(in: .whitespaces).isEmpty }\n", " return labeledFiles(fnames: fnames)\n", " } catch {\n", " print(\"Error labeling files\")\n", " return []\n", " }\n", "}\n", "*/\n", "\n", "let res = labeledFiles(fnames: sampleValFiles)\n", "print (\"Labels: \\(res.labels.shape) \\n \\(res.labels)\")\n", "print (\"Fnames: \\(res.fnames)\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Processing batch 0 TensorShape(dimensions: [2, 32, 32, 3])\r\n", "Processing batch 1 TensorShape(dimensions: [2, 32, 32, 3])\r\n", "Processing batch 2 TensorShape(dimensions: [2, 32, 32, 3])\r\n", "Processing batch 3 TensorShape(dimensions: [2, 32, 32, 3])\r\n", "Processing batch 4 TensorShape(dimensions: [2, 32, 32, 3])\r\n", "Processing batch 5 TensorShape(dimensions: [2, 32, 32, 3])\r\n", "Processing batch 6 TensorShape(dimensions: [2, 32, 32, 3])\r\n", "Processing batch 7 TensorShape(dimensions: [1, 32, 32, 3])\r\n" ] } ], "source": [ "// TODO: Not tested.\n", "func imagenetteDataBatch(\n", " _ input: LabeledImagenetteFiles\n", ") -> DataBatch, Tensor> {\n", " return DataBatch(\n", " xb: resizeImage(filename: input.fnames),\n", " yb: input.labels)\n", "}\n", "\n", "func imagenetteDataset(\n", " _ input: LabeledImagenetteFiles \n", ") -> Dataset, Tensor>> {\n", " return Dataset(\n", " elements: labeledFiles(fnames: sampleValFiles)\n", " ).map(imagenetteDataBatch)\n", "}\n", "\n", "func imagenetteDataBunch(trainFiles: String, valFiles: String, bs: Int = 64\n", ") -> DataBunch, Tensor>> {\n", " let trainDS = imagenetteDataset(labeledFiles(fnames: sampleTrainFiles))\n", " let valDS = imagenetteDataset(labeledFiles(fnames: sampleValFiles))\n", " return DataBunch(\n", " train: trainDS.batched(Int64(bs)), \n", " valid: valDS.batched(Int64(bs)))\n", "}\n", "\n", "let data = imagenetteDataBunch(\n", " trainFiles: \"imagenette-train-files.txt\", \n", " valFiles: \"imagenette-val-files.txt\", \n", " bs:2)\n", "\n", "for (i, d) in data.train.enumerated() {\n", " print(\"Processing batch \\(i) \\(d.xb.shape)\")\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Swift", "language": "swift", "name": "swift" } }, "nbformat": 4, "nbformat_minor": 2 }