Created
January 7, 2015 04:47
-
-
Save xccds/083b1d2ddf1ffc04c6f1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "", | |
"signature": "sha256:1e9219af12b0969ac2d8a0c71a4a6eb778998e8eba86ccb88dc905343f5993b0" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"- theano\u662fpython\u7684\u4e00\u4e2a\u5de5\u5177\u5e93\uff0c\u517c\u6709\u7b26\u53f7\u8ba1\u7b97\u548c\u6570\u503c\u8ba1\u7b97\u4e4b\u957f\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u662f\u6df7\u5408\u4e86mathmatica\u548cmatlab\u3002\u5b83\u7684\u4e3b\u8981\u529f\u80fd\u662f\u4f5c\u4e3a\u5b9e\u73b0\u5404\u79cd\u673a\u5668\u5b66\u4e60\u7b97\u6cd5\u7684\u51fd\u6570\u5e93\u3002\n", | |
"- \u56fe\u50cf\u5377\u79ef\u5c31\u662f\u4f7f\u7528\u4e00\u4e9b\u6743\u91cd\u77e9\u9635\u5bf9\u56fe\u50cf\u8fdb\u884c\u52a0\u6743\u5e73\u5747\uff0c\u8fd9\u4e9b\u6743\u91cd\u77e9\u9635\u79f0\u4e4b\u4e3a\u5377\u79ef\u6838\uff0c\u6216\u662f\u5377\u79ef\u6a21\u677f\u3002\n", | |
" - \u53c2\u8003\u6587\u6863\uff1a http://www.generation5.org/content/2002/convolution.asp\n", | |
"- \u5377\u79ef\u795e\u7ecf\u7f51\u7edc\u901a\u5e38\u6709\u56db\u79cd\u4e0d\u540c\u7c7b\u578b\u7684\u5c42\u6784\u6210\u3002\n", | |
" - \u6700\u540e\u7684\u8f93\u51fa\u5c42\u5c31\u662f\u4e00\u4e2a\u666e\u901a\u7684logistic\u56de\u5f52\n", | |
" - \u56de\u5f52\u5c42\u524d\u9762\u7684\u8f93\u5165\u5c42\u5c31\u662fMLP\u4e2d\u5e38\u89c1\u7684\u9690\u85cf\u5c42\uff0c\u5404\u795e\u7ecf\u5143\u662f\u5168\u8fde\u63a5\u7684\n", | |
" - \u6700\u524d\u9762\u7684\u662f\u4e00\u4e2a\u5377\u79ef\u5c42\uff0c\u901a\u8fc7\u4e00\u4e2a\u968f\u673a\u521d\u59cb\u5316\u7684\u5377\u79ef\u6a21\u677f\u5c06\u539f\u59cb\u8f93\u5165\u77e9\u9635\u8fdb\u884c\u7279\u5f81\u6620\u5c04\n", | |
" - \u8fd9\u79cd\u5377\u79ef\u6a21\u677f\u4f1a\u6709\u591a\u4e2a\uff0cn\u4e2a\u5377\u79ef\u6a21\u677f\u4f1a\u5c06\u539f\u59cb\u8f93\u5165\u5c42\u53d8\u6210n\u4e2a\u7279\u5f81\u6620\u5c04\uff0c\u8fd9n\u4e2a\u7279\u5f81\u6620\u5c04\u5728\u540c\u4e00\u5c42\u4e2d\n", | |
" - \u5377\u79ef\u5c42\u540e\u9762\u4f1a\u8ddf\u4e00\u4e2a\u6c60\u5316\u5c42\uff0c\u5c31\u662f\u5e73\u5747\u5316\u4e00\u4e0b\uff0c\u51cf\u5c11\u795e\u7ecf\u5143\u4e2a\u6570\n", | |
" - \u8fd9\u79cd\u5377\u79ef-\u6c60\u5316\u5c42\u4f1a\u6709\u591a\u4e2a\uff0c\u6700\u540e\u8f93\u51fa\u7ed9\u5230\u9690\u85cf\u5c42\n", | |
" - \u4e00\u4e2a\u5f88\u597d\u7684\u53c2\u8003\u6587\u6863\uff1a http://ibillxia.github.io/blog/2013/04/06/Convolutional-Neural-Networks/\n", | |
"- \u4e0b\u9762\u7684\u793a\u4f8b\u662fkaggle\u4e0a\u7684\u624b\u5199\u8bc6\u522b\uff0c\u5728\u53c2\u8003\u6587\u6863\u57fa\u7840\u4e0a\u4fee\u6539\u4e86\u6587\u4ef6\u8bfb\u53d6\u548c\u9884\u6d4b\u8f93\u51fa\u51fd\u6570\n", | |
" - \u53ea\u8fed\u4ee3100\u6b21\uff0c\u6392\u4f4d\u572850\u4f4d\u5de6\u53f3\uff0c\u5982\u679c\u6b21\u6570\u591a\u4e9b\u53ef\u80fd\u4f1a\u66f4\u9ad8\u4e9b\n", | |
" - \u53c2\u8003\u6587\u6863\uff1a http://deeplearning.net/tutorial/lenet.html#lenet" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"from sklearn.cross_validation import train_test_split\n", | |
"from sklearn.metrics import classification_report\n", | |
"import numpy as np\n", | |
"import pandas as pd" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"data = pd.read_csv('train.csv')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u627e\u5230X\u53d8\u91cf\u540d\n", | |
"select_x = data.columns != 'label'\n", | |
"# \u5c06X\u548cY\u5206\u5f00\n", | |
"data_x = (data.ix[:, select_x]/255).values\n", | |
"data_y = data.label.values" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import matplotlib.pylab as plt\n", | |
"%matplotlib inline" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"temp = data_x[1,:].reshape(28,28)\n", | |
"plt.imshow(temp);" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "display_data", | |
"png": "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\ngg==\n", | |
"text": [ | |
"<matplotlib.figure.Figure at 0x1044450d0>" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import cPickle\n", | |
"import time\n", | |
"import numpy\n", | |
"import theano\n", | |
"import theano.tensor as T" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Couldn't import dot_parser, loading of dot files will not be possible.\n" | |
] | |
} | |
], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u5efa\u7acblogistic\u56de\u5f52\u7c7b\uff0c\u4f5c\u4e3a\u6700\u540e\u4e00\u5c42\u8f93\u51fa\n", | |
"\n", | |
"class LogisticRegression(object):\n", | |
" # \u521d\u59cb\u5316\u5b9a\u4e49\u53c2\u6570\u5c5e\u6027\n", | |
" def __init__(self, input, n_in, n_out):\n", | |
" # initialize with 0 the weights W as a matrix of shape (n_in, n_out)\n", | |
" self.W = theano.shared(\n", | |
" value=numpy.zeros(\n", | |
" (n_in, n_out),\n", | |
" dtype=theano.config.floatX\n", | |
" ),\n", | |
" name='W',\n", | |
" borrow=True\n", | |
" )\n", | |
" # initialize the baises b as a vector of n_out 0s\n", | |
" self.b = theano.shared(\n", | |
" value=numpy.zeros(\n", | |
" (n_out,),\n", | |
" dtype=theano.config.floatX\n", | |
" ),\n", | |
" name='b',\n", | |
" borrow=True\n", | |
" )\n", | |
" self.p_y_given_x = T.nnet.softmax(T.dot(input, self.W) + self.b)\n", | |
" self.y_pred = T.argmax(self.p_y_given_x, axis=1)\n", | |
" self.params = [self.W, self.b]\n", | |
"\n", | |
" \n", | |
" def negative_log_likelihood(self, y):\n", | |
" return -T.mean(T.log(self.p_y_given_x)[T.arange(y.shape[0]), y])\n", | |
" \n", | |
" def errors(self, y):\n", | |
" # check if y has same dimension of y_pred\n", | |
" if y.ndim != self.y_pred.ndim:\n", | |
" raise TypeError(\n", | |
" 'y should have the same shape as self.y_pred',\n", | |
" ('y', y.type, 'y_pred', self.y_pred.type)\n", | |
" )\n", | |
" # check if y is of the correct datatype\n", | |
" if y.dtype.startswith('int'):\n", | |
" # the T.neq operator returns a vector of 0s and 1s, where 1\n", | |
" # represents a mistake in prediction\n", | |
" return T.mean(T.neq(self.y_pred, y))\n", | |
" else:\n", | |
" raise NotImplementedError()\n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 114 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u5b9a\u4e49\u4e00\u4e2a\u8bfb\u5165\u6570\u636e\u7684\u51fd\u6570\uff0c\u5c06\u6570\u503c\u6570\u636e\u8f6c\u4e3atheano\u7684\u683c\u5f0f\n", | |
"def shared_dataset(data_x,data_y):\n", | |
" shared_x = theano.shared(numpy.asarray(data_x, dtype=theano.config.floatX))\n", | |
" shared_y = theano.shared(numpy.asarray(data_y, dtype=theano.config.floatX))\n", | |
" return shared_x, T.cast(shared_y, 'int32')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u5b9a\u4e49\u9690\u85cf\u5c42\u5bf9\u8c61\uff0c\u5373MLP\u4e2d\u7684\u5168\u8fde\u63a5\u5c42\n", | |
"class HiddenLayer(object):\n", | |
" def __init__(self, rng, input, n_in, n_out, W=None, b=None,\n", | |
" activation=T.tanh):\n", | |
" self.input = input\n", | |
" if W is None:\n", | |
" W_values = numpy.asarray(\n", | |
" rng.uniform(\n", | |
" low=-numpy.sqrt(6. / (n_in + n_out)),\n", | |
" high=numpy.sqrt(6. / (n_in + n_out)),\n", | |
" size=(n_in, n_out)\n", | |
" ),\n", | |
" dtype=theano.config.floatX\n", | |
" )\n", | |
" if activation == theano.tensor.nnet.sigmoid:\n", | |
" W_values *= 4\n", | |
"\n", | |
" W = theano.shared(value=W_values, name='W', borrow=True)\n", | |
"\n", | |
" if b is None:\n", | |
" b_values = numpy.zeros((n_out,), dtype=theano.config.floatX)\n", | |
" b = theano.shared(value=b_values, name='b', borrow=True)\n", | |
"\n", | |
" self.W = W\n", | |
" self.b = b\n", | |
"\n", | |
" lin_output = T.dot(input, self.W) + self.b\n", | |
" self.output = (\n", | |
" lin_output if activation is None\n", | |
" else activation(lin_output)\n", | |
" )\n", | |
" # parameters of the model\n", | |
" self.params = [self.W, self.b]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 11 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u5b9a\u4e49\u5377\u79ef-\u6c60\u5316\u5c42\u5bf9\u8c61\n", | |
"class LeNetConvPoolLayer(object):\n", | |
" # \u521d\u59cb\u5316\u5b9a\u4e49\u8f93\u5165\u5c42\u7684\u7ef4\u5ea6\u548c\u5377\u79ef\u6838\u7684\u7ef4\u5ea6\uff0c\u4ee5\u53ca\u6c60\u5316\u77e9\u9635\u5927\u5c0f\n", | |
" # image_shape\u662f\u4e00\u4e2a\u56db\u7ef4\u6570\u7ec4\uff0c\u5206\u522b\u662f\u8f93\u5165\u6837\u672c\u6570, \u7279\u5f81\u6620\u5c04\u4e2a\u6570, \u957f\uff0c\u5bbd\n", | |
" # filter_shape\u4e5f\u662f\u4e00\u4e2a\u56db\u7ef4\u6570\u7ec4\uff0c\u5206\u522b\u662f\u5377\u79ef\u6838\u4e2a\u6570\uff0c\u8f93\u5165\u7684\u7279\u5f81\u6620\u5c04\u4e2a\u6570\uff0c\u957f\uff0c\u5bbd\n", | |
" def __init__(self, rng, input, filter_shape, image_shape, poolsize=(2, 2)):\n", | |
" assert image_shape[1] == filter_shape[1]\n", | |
" self.input = input\n", | |
" fan_in = numpy.prod(filter_shape[1:])\n", | |
" fan_out = (filter_shape[0] * numpy.prod(filter_shape[2:]) /\n", | |
" numpy.prod(poolsize))\n", | |
" # initialize weights with random weights\n", | |
" W_bound = numpy.sqrt(6. / (fan_in + fan_out))\n", | |
" self.W = theano.shared(\n", | |
" numpy.asarray(\n", | |
" rng.uniform(low=-W_bound, high=W_bound, size=filter_shape),\n", | |
" dtype=theano.config.floatX\n", | |
" ),\n", | |
" borrow=True\n", | |
" )\n", | |
" b_values = numpy.zeros((filter_shape[0],), dtype=theano.config.floatX)\n", | |
" self.b = theano.shared(value=b_values, borrow=True)\n", | |
"\n", | |
" # convolve input feature maps with filters\n", | |
" conv_out = conv.conv2d(\n", | |
" input=input,\n", | |
" filters=self.W,\n", | |
" filter_shape=filter_shape,\n", | |
" image_shape=image_shape\n", | |
" )\n", | |
"\n", | |
" # downsample each feature map individually, using maxpooling\n", | |
" pooled_out = downsample.max_pool_2d(\n", | |
" input=conv_out,\n", | |
" ds=poolsize,\n", | |
" ignore_border=True\n", | |
" )\n", | |
" self.output = T.tanh(pooled_out + self.b.dimshuffle('x', 0, 'x', 'x'))\n", | |
" self.params = [self.W, self.b]" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 21 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u5b9a\u4e49\u8bad\u7ec3\u4e3b\u51fd\u6570\n", | |
"def evaluate_lenet5(learning_rate=0.1, n_epochs=100,\n", | |
" data_x=data_x,data_y=data_y,\n", | |
" nkerns=[20, 50], batch_size=500):\n", | |
" # \u968f\u673a\u5212\u5206\u4e3a\u4e09\u7ec4\n", | |
" ind = numpy.random.choice([1,2,3],size=len(data_y),replace=True,p=[0.7,0.2,0.1])\n", | |
" train_x = data_x[ind==1,:]\n", | |
" train_y = data_y[ind==1]\n", | |
" valida_x = data_x[ind==2,:]\n", | |
" valida_y = data_y[ind==2]\n", | |
" test_x = data_x[ind==3,:]\n", | |
" test_y = data_y[ind==3]\n", | |
" train_set_x, train_set_y = shared_dataset(train_x,train_y)\n", | |
" valid_set_x, valid_set_y = shared_dataset(valida_x,valida_y)\n", | |
" test_set_x, test_set_y = shared_dataset(test_x, test_y)\n", | |
"\n", | |
" # compute number of minibatches for training, validation and testing\n", | |
" n_train_batches = train_set_x.get_value(borrow=True).shape[0] / batch_size\n", | |
" n_valid_batches = valid_set_x.get_value(borrow=True).shape[0] / batch_size\n", | |
" n_test_batches = test_set_x.get_value(borrow=True).shape[0] / batch_size\n", | |
"\n", | |
" # allocate symbolic variables for the data\n", | |
" index = T.lscalar() # index to a [mini]batch\n", | |
"\n", | |
" # start-snippet-1\n", | |
" x = T.matrix('x') # the data is presented as rasterized images\n", | |
" y = T.ivector('y') # the labels are presented as 1D vector of\n", | |
" # [int] labels\n", | |
"\n", | |
" ######################\n", | |
" # BUILD ACTUAL MODEL #\n", | |
" ######################\n", | |
" print '... building the model'\n", | |
"\n", | |
" layer0_input = x.reshape((batch_size, 1, 28, 28))\n", | |
" # \u7b2c0\u5c42\uff0c\u8f93\u5165\u6570\u636e\uff0c\u8fdb\u884c\u5377\u79ef\uff0c\u5c0628*28\u7684\u539f\u59cb\u6570\u636e\u5377\u79ef\u540e\u53d8\u621024*24\u6570\u636e\n", | |
" # \u670920\u4e2a\u5377\u79ef\u6838\uff0c\u56e0\u6b64\u5f62\u621020\u4e2a\u7279\u5f81\u6620\u5c04\uff08\u517120*24*24\u4e2a\u795e\u7ecf\u5143\uff09\n", | |
" # \u518d\u6c60\u5316\u540e\u53d8\u621012*12\n", | |
" layer0 = LeNetConvPoolLayer(\n", | |
" rng,\n", | |
" input=layer0_input,\n", | |
" image_shape=(batch_size, 1, 28, 28),\n", | |
" filter_shape=(nkerns[0], 1, 5, 5),\n", | |
" poolsize=(2, 2)\n", | |
" )\n", | |
" # \u7b2c1\u5c42\uff0c\u518d\u8fdb\u884c\u5377\u79ef\uff0c\u5c0612*12\u7684\u539f\u59cb\u6570\u636e\u5377\u79ef\u540e\u53d8\u62108*8\u6570\u636e\n", | |
" # \u5f62\u621050\u4e2a\u7279\u5f81\u6620\u5c04\uff0c\u518d\u6c60\u5316\u540e\u53d8\u62104*4\u6570\u636e\n", | |
" layer1 = LeNetConvPoolLayer(\n", | |
" rng,\n", | |
" input=layer0.output,\n", | |
" image_shape=(batch_size, nkerns[0], 12, 12),\n", | |
" filter_shape=(nkerns[1], nkerns[0], 5, 5),\n", | |
" poolsize=(2, 2)\n", | |
" )\n", | |
"\n", | |
" # \u5c06\u524d\u9762\u4e00\u5c42\u7684\u6570\u636e\u5e73\u5c55\u5f00\uff0c\u8f93\u5165\u5230\u5168\u8fde\u63a5\u7684\u9690\u85cf\u5c42\uff0c\u5171\u670950*4*4=800\u4e2a\u795e\u7ecf\u5143\n", | |
" # \u9690\u85cf\u5c42\u795e\u7ecf\u5143\u4e2a\u6570\u8bbe\u7f6e\u4e3a500\u4e2a\n", | |
" layer2_input = layer1.output.flatten(2)\n", | |
"\n", | |
" # construct a fully-connected sigmoidal layer\n", | |
" layer2 = HiddenLayer(\n", | |
" rng,\n", | |
" input=layer2_input,\n", | |
" n_in=nkerns[1] * 4 * 4,\n", | |
" n_out=500,\n", | |
" activation=T.tanh\n", | |
" )\n", | |
"\n", | |
" # \u6700\u540e\u8f93\u5165\u5230\u6700\u7ec8\u7684logistic\u56de\u5f52\u5c42\n", | |
" # \u8f93\u5165500\u4e2a\u795e\u7ecf\u5143\uff0c\u8f93\u51fa10\u4e2a\n", | |
" layer3 = LogisticRegression(input=layer2.output, n_in=500, n_out=10)\n", | |
"\n", | |
" # \u8ba1\u7b97cost function\n", | |
" cost = layer3.negative_log_likelihood(y)\n", | |
"\n", | |
" # create a function to compute the mistakes that are made by the model\n", | |
" test_model = theano.function(\n", | |
" [index],\n", | |
" layer3.errors(y),\n", | |
" givens={\n", | |
" x: test_set_x[index * batch_size: (index + 1) * batch_size],\n", | |
" y: test_set_y[index * batch_size: (index + 1) * batch_size]\n", | |
" }\n", | |
" )\n", | |
"\n", | |
" validate_model = theano.function(\n", | |
" [index],\n", | |
" layer3.errors(y),\n", | |
" givens={\n", | |
" x: valid_set_x[index * batch_size: (index + 1) * batch_size],\n", | |
" y: valid_set_y[index * batch_size: (index + 1) * batch_size]\n", | |
" }\n", | |
" )\n", | |
"\n", | |
" # \u4fdd\u5b58\u56db\u5c42\u795e\u7ecf\u5143\u7684\u6240\u6709\u53c2\u6570\n", | |
" params = layer3.params + layer2.params + layer1.params + layer0.params\n", | |
"\n", | |
" # \u521b\u5efacost\u7684\u68af\u5ea6\u51fd\u6570\n", | |
" grads = T.grad(cost, params)\n", | |
"\n", | |
" # \u4f7f\u7528\u968f\u673a\u68af\u5ea6\u4e0b\u964d\u7b97\u6cd5\u8ba1\u7b97\u53c2\u6570\n", | |
" updates = [\n", | |
" (param_i, param_i - learning_rate * grad_i)\n", | |
" for param_i, grad_i in zip(params, grads)\n", | |
" ]\n", | |
"\n", | |
" train_model = theano.function(\n", | |
" [index],\n", | |
" cost,\n", | |
" updates=updates,\n", | |
" givens={\n", | |
" x: train_set_x[index * batch_size: (index + 1) * batch_size],\n", | |
" y: train_set_y[index * batch_size: (index + 1) * batch_size]\n", | |
" }\n", | |
" )\n", | |
" # end-snippet-1\n", | |
"\n", | |
" ###############\n", | |
" # TRAIN MODEL #\n", | |
" ###############\n", | |
" print '... training'\n", | |
" # early-stopping parameters\n", | |
" patience = 10000 # look as this many examples regardless\n", | |
" patience_increase = 2 # wait this much longer when a new best is\n", | |
" # found\n", | |
" improvement_threshold = 0.995 # a relative improvement of this much is\n", | |
" # considered significant\n", | |
" validation_frequency = min(n_train_batches, patience / 2)\n", | |
" # go through this many\n", | |
" # minibatche before checking the network\n", | |
" # on the validation set; in this case we\n", | |
" # check every epoch\n", | |
"\n", | |
" best_validation_loss = numpy.inf\n", | |
" best_iter = 0\n", | |
" test_score = 0.\n", | |
" start_time = time.clock()\n", | |
"\n", | |
" epoch = 0\n", | |
" done_looping = False\n", | |
"\n", | |
" while (epoch < n_epochs) and (not done_looping):\n", | |
" epoch = epoch + 1\n", | |
" for minibatch_index in xrange(n_train_batches):\n", | |
"\n", | |
" iter = (epoch - 1) * n_train_batches + minibatch_index\n", | |
"\n", | |
" if iter % 100 == 0:\n", | |
" print 'training @ iter = ', iter\n", | |
" cost_ij = train_model(minibatch_index)\n", | |
"\n", | |
" if (iter + 1) % validation_frequency == 0:\n", | |
"\n", | |
" # compute zero-one loss on validation set\n", | |
" validation_losses = [validate_model(i) for i\n", | |
" in xrange(n_valid_batches)]\n", | |
" this_validation_loss = numpy.mean(validation_losses)\n", | |
" print('epoch %i, minibatch %i/%i, validation error %f %%' %\n", | |
" (epoch, minibatch_index + 1, n_train_batches,\n", | |
" this_validation_loss * 100.))\n", | |
"\n", | |
" # if we got the best validation score until now\n", | |
" if this_validation_loss < best_validation_loss:\n", | |
"\n", | |
" #improve patience if loss improvement is good enough\n", | |
" if this_validation_loss < best_validation_loss * \\\n", | |
" improvement_threshold:\n", | |
" patience = max(patience, iter * patience_increase)\n", | |
"\n", | |
" # save best validation score and iteration number\n", | |
" best_validation_loss = this_validation_loss\n", | |
" best_iter = iter\n", | |
"\n", | |
" # test it on the test set\n", | |
" test_losses = [\n", | |
" test_model(i)\n", | |
" for i in xrange(n_test_batches)\n", | |
" ]\n", | |
" test_score = numpy.mean(test_losses)\n", | |
" print((' epoch %i, minibatch %i/%i, test error of '\n", | |
" 'best model %f %%') %\n", | |
" (epoch, minibatch_index + 1, n_train_batches,\n", | |
" test_score * 100.))\n", | |
"\n", | |
" if patience <= iter:\n", | |
" done_looping = True\n", | |
" break\n", | |
"\n", | |
" end_time = time.clock()\n", | |
" print('Optimization complete.')\n", | |
" print('Best validation score of %f %% obtained at iteration %i, '\n", | |
" 'with test performance %f %%' %\n", | |
" (best_validation_loss * 100., best_iter + 1, test_score * 100.))\n", | |
" return params" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 337 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u5f00\u59cb\u8bad\u7ec3\n", | |
"dig_para = evaluate_lenet5()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 371 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u5efa\u7acb\u9884\u6d4b\u51fd\u6570" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def prediction(data_x=data_x, dig_para=dig_para, batch_size = 500):\n", | |
" shared_x = theano.shared(data_x)\n", | |
" x = T.matrix('x') # the data is presented as rasterized images\n", | |
" y = T.ivector('y') # the labels are presented as 1D vector of\n", | |
" # [int] labels\n", | |
" layer0_input = x.reshape((batch_size, 1, 28, 28)) \n", | |
" layer0 = LeNetConvPoolLayer(\n", | |
" rng,\n", | |
" input=layer0_input,\n", | |
" image_shape=(batch_size, 1, 28, 28),\n", | |
" filter_shape=(20, 1, 5, 5),\n", | |
" poolsize=(2, 2)\n", | |
" )\n", | |
" layer0.W.set_value(dig_para[6].get_value())\n", | |
" layer0.b.set_value(dig_para[7].get_value())\n", | |
" layer1 = LeNetConvPoolLayer(\n", | |
" rng,\n", | |
" input=layer0.output,\n", | |
" image_shape=(batch_size, 20, 12, 12),\n", | |
" filter_shape=(50,20, 5, 5),\n", | |
" poolsize=(2, 2)\n", | |
" )\n", | |
" layer1.W.set_value(dig_para[4].get_value())\n", | |
" layer1.b.set_value(dig_para[5].get_value())\n", | |
" layer2_input = layer1.output.flatten(2)\n", | |
"\n", | |
" layer2 = HiddenLayer(\n", | |
" rng,\n", | |
" input=layer2_input,\n", | |
" n_in=50 * 4 * 4,\n", | |
" n_out=500,\n", | |
" activation=T.tanh\n", | |
" )\n", | |
" layer2.W.set_value(dig_para[2].get_value())\n", | |
" layer2.b.set_value(dig_para[3].get_value())\n", | |
" layer3 = LogisticRegression(input=layer2.output, n_in=500, n_out=10)\n", | |
" layer3.W.set_value(dig_para[0].get_value())\n", | |
" layer3.b.set_value(dig_para[1].get_value())\n", | |
" pred_model = theano.function(\n", | |
" [index],\n", | |
" layer3.y_pred,\n", | |
" givens={\n", | |
" x: shared_x[index * batch_size: (index + 1) * batch_size] \n", | |
" }\n", | |
" )\n", | |
" n_batches=shared_x.get_value(borrow=True).shape[0] / batch_size\n", | |
" result = numpy.array([])\n", | |
" for i in xrange(n_batches):\n", | |
" result = numpy.append(result,pred_model(i))\n", | |
" return result" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 339 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u9884\u6d4btest.csv\u6570\u636e\uff0c\u5c06\u8f93\u51fa\u5199\u5165csv\u6587\u4ef6\uff0c\u63d0\u4ea4\u5230kaggle\u5927\u7ea6\u6392\u523050\u4f4d" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"test_data = pd.read_csv('test.csv')\n", | |
"test_x = (test_data/255).values" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 340 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"result = prediction(test_x)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 344 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Label = pd.Series(result)\n", | |
"ImageId = pd.Series(range(len(Label))) + 1\n", | |
"sub = pd.concat ([ImageId, Label],1)\n", | |
"sub.columns = ['ImageId', 'Label']\n", | |
"sub['Label'] = sub.Label.astype('int')\n", | |
"sub.to_csv('sub.csv',index =False)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 370 | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment