154 lines
5.5 KiB
Plaintext
154 lines
5.5 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"from scipy import optimize\n",
|
|
"\n",
|
|
"class Neural_Network(object):\n",
|
|
" def __init__(self, Lambda=0): \n",
|
|
" #Define Hyperparameters\n",
|
|
" self.inputLayerSize = 2\n",
|
|
" self.outputLayerSize = 1\n",
|
|
" self.hiddenLayerSize = 3\n",
|
|
" \n",
|
|
" #Weights (parameters)\n",
|
|
" self.W1 = np.random.randn(self.inputLayerSize,self.hiddenLayerSize)\n",
|
|
" self.W2 = np.random.randn(self.hiddenLayerSize,self.outputLayerSize)\n",
|
|
" \n",
|
|
" #Regularization Parameter:\n",
|
|
" self.Lambda = Lambda\n",
|
|
" \n",
|
|
" def forward(self, X):\n",
|
|
" #Propogate inputs though network\n",
|
|
" self.z2 = np.dot(X, self.W1)\n",
|
|
" self.a2 = self.sigmoid(self.z2)\n",
|
|
" self.z3 = np.dot(self.a2, self.W2)\n",
|
|
" yHat = self.sigmoid(self.z3) \n",
|
|
" return yHat\n",
|
|
" \n",
|
|
" def sigmoid(self, z):\n",
|
|
" #Apply sigmoid activation function to scalar, vector, or matrix\n",
|
|
" return 1/(1+np.exp(-z))\n",
|
|
" \n",
|
|
" def sigmoidPrime(self,z):\n",
|
|
" #Gradient of sigmoid\n",
|
|
" return np.exp(-z)/((1+np.exp(-z))**2)\n",
|
|
" \n",
|
|
" def costFunction(self, X, y):\n",
|
|
" #Compute cost for given X,y, use weights already stored in class.\n",
|
|
" self.yHat = self.forward(X)\n",
|
|
" J = 0.5*sum((y-self.yHat)**2)/X.shape[0] + (self.Lambda/2)*(np.sum(self.W1**2)+np.sum(self.W2**2))\n",
|
|
" return J\n",
|
|
" \n",
|
|
" def costFunctionPrime(self, X, y):\n",
|
|
" #Compute derivative with respect to W and W2 for a given X and y:\n",
|
|
" self.yHat = self.forward(X)\n",
|
|
" \n",
|
|
" delta3 = np.multiply(-(y-self.yHat), self.sigmoidPrime(self.z3))\n",
|
|
" #Add gradient of regularization term:\n",
|
|
" dJdW2 = np.dot(self.a2.T, delta3)/X.shape[0] + self.Lambda*self.W2\n",
|
|
" \n",
|
|
" delta2 = np.dot(delta3, self.W2.T)*self.sigmoidPrime(self.z2)\n",
|
|
" #Add gradient of regularization term:\n",
|
|
" dJdW1 = np.dot(X.T, delta2)/X.shape[0] + self.Lambda*self.W1\n",
|
|
" \n",
|
|
" return dJdW1, dJdW2\n",
|
|
" \n",
|
|
" #Helper functions for interacting with other methods/classes\n",
|
|
" def getParams(self):\n",
|
|
" #Get W1 and W2 Rolled into vector:\n",
|
|
" params = np.concatenate((self.W1.ravel(), self.W2.ravel()))\n",
|
|
" return params\n",
|
|
" \n",
|
|
" def setParams(self, params):\n",
|
|
" #Set W1 and W2 using single parameter vector:\n",
|
|
" W1_start = 0\n",
|
|
" W1_end = self.hiddenLayerSize*self.inputLayerSize\n",
|
|
" self.W1 = np.reshape(params[W1_start:W1_end], \\\n",
|
|
" (self.inputLayerSize, self.hiddenLayerSize))\n",
|
|
" W2_end = W1_end + self.hiddenLayerSize*self.outputLayerSize\n",
|
|
" self.W2 = np.reshape(params[W1_end:W2_end], \\\n",
|
|
" (self.hiddenLayerSize, self.outputLayerSize))\n",
|
|
" \n",
|
|
" def computeGradients(self, X, y):\n",
|
|
" dJdW1, dJdW2 = self.costFunctionPrime(X, y)\n",
|
|
" return np.concatenate((dJdW1.ravel(), dJdW2.ravel()))\n",
|
|
" \n",
|
|
" \n",
|
|
"class trainer(object):\n",
|
|
" def __init__(self, N):\n",
|
|
" #Make Local reference to network:\n",
|
|
" self.N = N\n",
|
|
" \n",
|
|
" def callbackF(self, params):\n",
|
|
" self.N.setParams(params)\n",
|
|
" self.J.append(self.N.costFunction(self.X, self.y))\n",
|
|
" self.testJ.append(self.N.costFunction(self.testX, self.testY))\n",
|
|
" \n",
|
|
" def costFunctionWrapper(self, params, X, y):\n",
|
|
" self.N.setParams(params)\n",
|
|
" cost = self.N.costFunction(X, y)\n",
|
|
" grad = self.N.computeGradients(X,y)\n",
|
|
" return cost, grad\n",
|
|
" \n",
|
|
" def train(self, trainX, trainY, testX, testY):\n",
|
|
" #Make an internal variable for the callback function:\n",
|
|
" self.X = trainX\n",
|
|
" self.y = trainY\n",
|
|
" \n",
|
|
" self.testX = testX\n",
|
|
" self.testY = testY\n",
|
|
"\n",
|
|
" #Make empty list to store training costs:\n",
|
|
" self.J = []\n",
|
|
" self.testJ = []\n",
|
|
" \n",
|
|
" params0 = self.N.getParams()\n",
|
|
"\n",
|
|
" options = {'maxiter': 200, 'disp' : True}\n",
|
|
" _res = optimize.minimize(self.costFunctionWrapper, params0, jac=True, method='BFGS', \\\n",
|
|
" args=(trainX, trainY), options=options, callback=self.callbackF)\n",
|
|
"\n",
|
|
" self.N.setParams(_res.x)\n",
|
|
" self.optimizationResults = _res\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.6.3"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|