{"cells":[{"metadata":{"_uuid":"2c530d6913036a7104242ff09e8dfd4fc0f5143d"},"cell_type":"markdown","source":"这是我第一次在 Kaggle 上“手写”代码。\n\n本次尝试使用 TensorFlow 实现的  Keras API 规范代码库，而非直接使用 Keras 代码库。\n\n关于 TensorFlow 实现的  Keras API 规范代码库，详见其网站。\n\n文档网址为：https://www.tensorflow.org/guide/keras\n\n**导入数据、规范数据**"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"483bfcff033c2e06f0c3806388e12cbf7b0e1462"},"cell_type":"code","source":"# 设置基本参数\nbatch_size=32\nepochs=20\nnum_classes=10\ninput_shape=(28,28,1)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# 导入测试集的数据\ntrain = pd.read_csv('../input/train.csv')\ntest = pd.read_csv('../input/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7759c08796735c4aef101bdf70ba549db98030a9"},"cell_type":"code","source":"# train 为 42000 * 785矩阵，X_train 取后784列，Y_train 取第一列（即标签）\n# test 为 28000 * 784矩阵\nX_train = train.iloc[:, 1:].values\nY_train = train.iloc[:, 0].values\nX_test = test.values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"83f3009a1bc655e7286f0560667dcb1bcc2e41b9"},"cell_type":"code","source":"# 节约少许内存开销（约400M）\ndel train, test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"316bf825576487dd1584ec910166a17151494661"},"cell_type":"code","source":"# 将二维矩阵 42000 * 784\n# 转换成四维矩阵，42000 * 28 * 28 * 1\nX_train = X_train.reshape(X_train.shape[0], 28, 28, 1)\nX_test = X_test.reshape(X_test.shape[0], 28, 28, 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c9dcc875530566147eb29ff15cf5139df9b4bdac"},"cell_type":"code","source":"# 将 0-255 的数据，归化为 0-1 的数据\nX_train = np.divide(X_train, 255.)\nX_test = np.divide(X_test, 255.)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a2a1c9804f6b8c8093573ff9203d06ba64b0790b"},"cell_type":"markdown","source":"**三步走：训练模型、验证模型、作出预测**"},{"metadata":{"trusted":true,"_uuid":"6c6b8d96761ec38ba206117294541c41fba2e55e"},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\n\n# 打印版本号\nprint(tf.__version__)\nprint(keras.__version__)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3cd417c34b55d2706960493be4a44b3f2a36041a"},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# 将 Y_train 也即2维的 42000 * 1 矩阵，按 one-shot 编码为 42000 * 10的矩阵\n# 原值 0-9 的数值转换为 1 * 10 的列对应为1，其余为0\nY_train = keras.utils.to_categorical(Y_train, num_classes)\n\n# 将样本 42000 切分为训练组 train 和校验组 val 两组数据\n# 参数 train_size / test_size 既可按比例切分，也可以直接指定数量\nX_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size = 2000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bdea96f6c12d60dac76a71749d606cfd95bfe789"},"cell_type":"code","source":"# define a model with tensorflow.keras\nmodel = keras.Sequential()\n\n# 填充方式 same 或 valid，大小写敏感！\nmodel.add(keras.layers.Conv2D(filters=32, kernel_size=(3,3), activation='relu', padding='same',\n                              input_shape=input_shape))\nmodel.add(keras.layers.Conv2D(filters=64, kernel_size=(3,3), activation='relu', padding='same'))\nmodel.add(keras.layers.MaxPool2D(pool_size=(2,2)))\nmodel.add(keras.layers.Dropout(rate=0.25))\n\nmodel.add(keras.layers.Flatten())\nmodel.add(keras.layers.Dense(units=128, activation='relu'))\nmodel.add(keras.layers.Dropout(rate=0.5))\nmodel.add(keras.layers.Dense(units=10, activation='softmax'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"83fbd45ed6a5568612ac65c3e6a0c6445e31bae8"},"cell_type":"code","source":"# 用以生成一个batch的图像数据，支持实时数据提升\ndatagen = keras.preprocessing.image.ImageDataGenerator(\n        featurewise_center=False,  # set input mean to 0 over the dataset\n        samplewise_center=False,  # set each sample mean to 0\n        featurewise_std_normalization=False,  # divide inputs by std of the dataset\n        samplewise_std_normalization=False,  # divide each input by its std\n        zca_whitening=False,  # apply ZCA whitening\n        rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)\n        zoom_range = 0.1, # Randomly zoom image\n        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)\n        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)\n        horizontal_flip=False,  # randomly flip images\n        vertical_flip=False)  # randomly flip images","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5d7431b0d9fcc06e96ec053288a95068a69d6754"},"cell_type":"code","source":"# 修改学习率\nlearning_rate_reduction = keras.callbacks.ReduceLROnPlateau(monitor='val_acc',patience=3,verbose=2,factor=0.5,min_lr=0.00001)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fdbf73ad1b3b1d5bd54c0ae4efae43d175cc1c72"},"cell_type":"code","source":"# 编译模型\noptimizer=keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)\n\nmodel.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4279cc3ebf7f64f89d98ad20f28f176942577f0d"},"cell_type":"code","source":"# 训练模型\nhistory = model.fit_generator(datagen.flow(X_train, Y_train, batch_size=batch_size),\n                              epochs =epochs, validation_data = (X_val,Y_val),\n                              verbose = 2, steps_per_epoch=X_train.shape[0] // batch_size+1,\n                              callbacks=[learning_rate_reduction])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"707605b544461bed53d8d3ea28966dc95cb7906d"},"cell_type":"code","source":"# 测试模型\nloss, accuracy = model.evaluate(X_val, Y_val, steps=batch_size)\nloss, accuracy","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"009077345458be5bb9954bc7e83eebf0bb2d49ec"},"cell_type":"code","source":"# 作出预测\npredicted = model.predict(X_test)\n\n# 将预测结果 28000 * 10 处理成 28000 * 1\n# 算法是取 10 个值中的最大值\nresults = np.argmax(predicted, axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ee18eedfe4b54068b0ad065f7e867b5454bdfa3b"},"cell_type":"code","source":"# 将预测值保存成竞赛要求的格式\nsubmission = pd.read_csv('../input/sample_submission.csv')\nsubmission[\"Label\"] = results\nsubmission.to_csv('tf_keras.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}