{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%install '.package(path: \"$cwd/FastaiNotebook_04_callbacks\")' FastaiNotebook_04_callbacks" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Demonstrating a simple MNIST model with an array of layers" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import FastaiNotebook_04_callbacks\n", "var data = mnistDataBunch(flat: true)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import TensorFlow\n", "\n", "struct DynamicModel: Layer {\n", " public var hiddens: [Dense]\n", " public var last: Dense\n", " \n", " init(nIn: Int, nHiddens: [Int], nOut: Int) {\n", " var nLast = nIn\n", " self.hiddens = []\n", " for nHidden in nHiddens {\n", " self.hiddens.append(Dense.init(inputSize: nLast, outputSize: nHidden, activation: relu))\n", " nLast = nHidden\n", " }\n", " self.last = Dense.init(inputSize: nLast, outputSize: nOut, activation: identity)\n", " }\n", " \n", " @differentiable\n", " func applied(to input: Tensor, in context: Context) -> Tensor {\n", " return input.sequenced(in: context, through: hiddens, last)\n", " }\n", "}\n", "\n", "/// Model with a fixed number of layers, for comparison.\n", "struct FixedModel: Layer {\n", " public var layer1: Dense\n", " public var layer2: Dense\n", " public var layer3: Dense\n", " \n", " public init(nIn: Int, nHid: Int, nOut: Int){\n", " layer1 = Dense(inputSize: nIn, outputSize: nHid, activation: relu)\n", " layer2 = Dense(inputSize: nHid, outputSize: nHid)\n", " layer3 = Dense(inputSize: nHid, outputSize: nOut)\n", " }\n", " \n", " @differentiable\n", " public func applied(to input: Tensor, in context: Context) -> Tensor {\n", " return input.sequenced(in: context, through: layer1, layer2, layer3)\n", " }\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "let nIn = 784\n", "let nHid = 50\n", "let nOut = 10\n", "\n", "let modelDynamic = DynamicModel(nIn: nIn, nHiddens: [nHid, nHid], nOut: nOut)\n", "var modelFixed = FixedModel(nIn: nIn, nHid: nHid, nOut: nOut)\n", "\n", "// Turn off shuffling, and make the model weights the same, to verify that both models do the same thing.\n", "data.shuffleTrain = false\n", "modelFixed.layer1 = modelDynamic.hiddens[0]\n", "modelFixed.layer2 = modelDynamic.hiddens[1]\n", "modelFixed.layer3 = modelDynamic.last\n", "\n", "let optDynamic = SimpleSGD(learningRate: 1e-2)\n", "func modelInitDynamic() -> DynamicModel { return modelDynamic }\n", "let learnerDynamic = Learner(data: data, lossFunction: softmaxCrossEntropy, optimizer: optDynamic, initializingWith: modelInitDynamic)\n", "learnerDynamic.delegates = [learnerDynamic.makeTrainEvalDelegate(), learnerDynamic.makeAvgMetric(metrics: [accuracy])]\n", "\n", "let optFixed = SimpleSGD(learningRate: 1e-2)\n", "func modelInitFixed() -> FixedModel { return modelFixed }\n", "let learnerFixed = Learner(data: data, lossFunction: softmaxCrossEntropy, optimizer: optFixed, initializingWith: modelInitFixed)\n", "learnerFixed.delegates = [learnerFixed.makeTrainEvalDelegate(), learnerFixed.makeAvgMetric(metrics: [accuracy])]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learnerDynamic.fit(3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learnerFixed.fit(3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Swift", "language": "swift", "name": "swift" }, "language_info": { "file_extension": ".swift", "mimetype": "text/x-swift", "name": "swift", "version": "" } }, "nbformat": 4, "nbformat_minor": 2 }