{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport os\n\n#读取数据，提取训练集和测试集\ntrain  = pd.read_csv('../input/digit-recognizer/train.csv')\ntest = pd.read_csv('../input/digit-recognizer/test.csv')\nx_train = (train.iloc[:,1:].values).astype(np.float)\nx_test = (test.values).astype(np.float)\n#线性归一化，加快收敛速度，利于梯度下降\nx_train = np.multiply(x_train, 1.0/255)\nx_test = np.multiply(x_test, 1.0/255)\n#相关变量设置\nimage_size = x_train.shape[1]\nimage_width = image_height = np.ceil(np.sqrt(image_size)).astype(np.uint8)\nlabel_train = train.iloc[:,0].values\nlabel_count = np.unique(label_train).shape[0]\n\n#独热编码，用于神经网络FC层后输出分类，例如数字4=[0,0,0,1,0,0,0,0,0,0]\ndef one_hot(label_dense, count):\n    num_label = label_dense.shape[0]\n    index_offset = np.arange(num_label) * count\n    label_one_hot = np.zeros((num_label, count))\n    label_one_hot.flat[index_offset + label_dense.ravel()] = 1\n    return label_one_hot\n\nlabels = one_hot(label_train, label_count)\nlabels = labels.astype(np.uint8)\n\n#设定batchsize\nbatch_size = 100\nn_batch = int(x_train.shape[0] / batch_size)\nx = tf.placeholder(tf.float32, [None, 784])\ny = tf.placeholder(tf.float32, [None, 10])\n\n#权重矩阵初始化，正态分布，mean=0， stddev=0.1\ndef weight_variable(shape):\n    initial = tf.truncated_normal(shape, mean = 0, stddev = 0.1)\n    return tf.Variable(initial)\n\n#偏置矩阵初始化，常值0.05\ndef bias_variable(shape):\n    initial = tf.constant(0.05, shape = shape)\n    return tf.Variable(initial)\n\n#卷积，滑动步长在两个方向均为strides[1]=strides[2]=1\ndef conv2d(x, w):\n    return tf.nn.conv2d(x, w, strides = [1, 1, 1, 1], padding = 'SAME')\n\n#卷积，滑动步长在两个方向均为strides[1]=strides[2]=2\ndef conv2ds2(x, w):\n    return tf.nn.conv2d(x, w, strides = [1, 2, 2, 1], padding = 'SAME')\n\n#池化，滑动步长在两个方向均为strides[1]=strides[2]=2，做2x2中的maxpool\ndef max_pool_2x2(x):\n    return tf.nn.max_pool(x, ksize = [1, 2, 2, 1], strides = [1, 2, 2, 1], padding = 'SAME')\n\n#x原本为长度784的行向量，reshape为具有宽高的矩阵\nx_image = tf.reshape(x, [-1, 28, 28, 1])\n\n#第1层conv->relu\n#28x28 -> 28x28 每个输入产生32个特征图\nW_conv1 = weight_variable([3, 3, 1, 32])\nb_conv1 = bias_variable([32])\nh_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)\n\n#第2层conv->relu\n#28x28 -> 28x28 每个输入产生32个特征图\nW_conv2 = weight_variable([3, 3, 32, 32])\nb_conv2 = bias_variable([32])\nh_conv2 = tf.nn.relu(conv2d(h_conv1, W_conv2) + b_conv2)\n\n#第3层conv->relu\n#28x28->  14x14 ，每个输入产生64个特征图\nW_conv3 = weight_variable([5, 5, 32, 32])\nb_conv3 = bias_variable([32])\nh_conv3 = tf.nn.relu(conv2ds2(h_conv2, W_conv3) + b_conv3)\n\n#第4层conv->relu\n#14x14 -> 14x14 , 每个输入产生64个特征图\nW_conv4 = weight_variable([3, 3, 32, 64])\nb_conv4 = bias_variable([64])\nh_conv4 = tf.nn.relu(conv2d(h_conv3, W_conv4) + b_conv4)\n\n#第5层conv->relu\n#14x14 -> 14x14 每个输入产生64个特征图\nW_conv5 = weight_variable([3, 3, 64, 64])\nb_conv5 = bias_variable([64])\nh_conv5 = tf.nn.relu(conv2d(h_conv4, W_conv5) + b_conv5)\n\n#第6层conv->relu\n#14x14 ->  7x7 ，每个输入产生64个特征图\nW_conv6 = weight_variable([5, 5, 64, 64])\nb_conv6 = bias_variable([64])\nh_conv6 = tf.nn.relu(conv2ds2(h_conv5, W_conv6) + b_conv6)\n\n#第5层fc->relu+dropout，防止过拟合\n#所有的特征reshape成一列，7x7x64 -> 128\nh_conv6_flat = tf.reshape(h_conv6, [-1, 7*7*64])\nw_fc1 = weight_variable([7*7*64, 1024])\nb_fc1 = bias_variable([1024])\nh_fc1 = tf.nn.relu(tf.matmul(h_conv6_flat, w_fc1) + b_fc1)\nkeep_prob = tf.placeholder(tf.float32)\nh_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)\n\n#第6层fc->softmax\n#128 -> 10，生成prediction\nw_fc2 = weight_variable([1024, 10])\nb_fc2 = bias_variable([10])\ny_conv = tf.matmul(h_fc1_drop, w_fc2) + b_fc2\nprediction = tf.nn.softmax(y_conv)\n\n#softmax->求交叉熵->平均求loss\nloss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = y, logits = y_conv))\n#优化器优化loss，learning_rate = 0.1 \ntrain_step_1 = tf.train.AdadeltaOptimizer(0.1).minimize(loss)\n#argmax返回每行最大值索引，即每个图片的label，equal逐个元素判断是否相同\ncorrection_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_conv, 1))\n#boolean转化为float，求准确率\naccuracy = tf.reduce_mean(tf.cast(correction_prediction, tf.float32))\n\nglobal_step = tf.Variable(0, name = 'global_step', trainable = False)\n\n#初始化变量\ninit = tf.global_variables_initializer()\n#训练结果保存在saver\nsaver = tf.train.Saver()\n\nwith tf.Session() as sess:\n    #初始化\n    sess.run(init)\n    #迭代20次\n    for epoch in range(30):\n        print('epoch', epoch+1)\n        #每批100个样本\n        for batch in range(n_batch):\n            batch_x = x_train[(batch) * batch_size : (batch + 1) * batch_size]\n            batch_y = labels[(batch) * batch_size : (batch + 1) * batch_size]\n            sess.run(train_step_1, feed_dict = {x : batch_x, y : batch_y, keep_prob : 0.6})\n        batch_x = x_train[n_batch * batch_size:]\n        batch_y = labels[n_batch * batch_size:]\n        sess.run(train_step_1, feed_dict = {x : batch_x, y : batch_y, keep_prob : 0.6})\n    #保存模型参数\n    saver.save(sess, 'model.ckpt')\n    saver.restore(sess, 'model.ckpt')\n    filename = 'cnn_result.csv'\n    #用测试集开始预测\n    test_batch = x_test[:]\n    myPrediction = sess.run(prediction, feed_dict = {x : test_batch, keep_prob : 1.0})\n    label_test = np.argmax(myPrediction, axis = 1)\n    result = pd.Series(label_test, name='Label')\n    submission = pd.concat([pd.Series(range(1, 28001), name = 'ImageId'), result], axis = 1)\n    submission.to_csv(filename, index = False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}