{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport seaborn as sns\n%matplotlib inline\n\nnp.random.seed(2)\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix\nimport itertools\n\nfrom keras.utils.np_utils import to_categorical # convert to one-hot-encoding\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D\nfrom tensorflow.keras.optimizers import RMSprop\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import ReduceLROnPlateau\n\n\nsns.set(style='white', context='notebook', palette='deep')\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-14T02:35:48.538546Z","iopub.execute_input":"2022-07-14T02:35:48.541672Z","iopub.status.idle":"2022-07-14T02:35:54.633927Z","shell.execute_reply.started":"2022-07-14T02:35:48.541609Z","shell.execute_reply":"2022-07-14T02:35:54.632854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\nY = train_data[\"label\"]\ntrain_data = train_data.drop(labels = [\"label\"],axis=1)\ntrain_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:35:54.635884Z","iopub.execute_input":"2022-07-14T02:35:54.636377Z","iopub.status.idle":"2022-07-14T02:35:57.834011Z","shell.execute_reply.started":"2022-07-14T02:35:54.636350Z","shell.execute_reply":"2022-07-14T02:35:57.832855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")\ntest_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:35:57.835703Z","iopub.execute_input":"2022-07-14T02:35:57.836295Z","iopub.status.idle":"2022-07-14T02:35:59.906435Z","shell.execute_reply.started":"2022-07-14T02:35:57.836259Z","shell.execute_reply":"2022-07-14T02:35:59.905494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import seaborn as sns\nsns.countplot(Y)","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:35:59.909376Z","iopub.execute_input":"2022-07-14T02:35:59.909725Z","iopub.status.idle":"2022-07-14T02:36:00.172564Z","shell.execute_reply.started":"2022-07-14T02:35:59.909691Z","shell.execute_reply":"2022-07-14T02:36:00.171644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.isnull().any().describe()","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:00.174878Z","iopub.execute_input":"2022-07-14T02:36:00.175536Z","iopub.status.idle":"2022-07-14T02:36:00.196266Z","shell.execute_reply.started":"2022-07-14T02:36:00.175497Z","shell.execute_reply":"2022-07-14T02:36:00.195155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data.isnull().any().describe()","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:00.198054Z","iopub.execute_input":"2022-07-14T02:36:00.198419Z","iopub.status.idle":"2022-07-14T02:36:00.215871Z","shell.execute_reply.started":"2022-07-14T02:36:00.198385Z","shell.execute_reply":"2022-07-14T02:36:00.214801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#标准化\ntest_data = test_data / 255.0\ntrain_data = train_data/255.0","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:00.217640Z","iopub.execute_input":"2022-07-14T02:36:00.217995Z","iopub.status.idle":"2022-07-14T02:36:00.392268Z","shell.execute_reply.started":"2022-07-14T02:36:00.217961Z","shell.execute_reply":"2022-07-14T02:36:00.391232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#重塑数据形状\ntrain_data = train_data.values.reshape(-1,28,28,1)\ntest_data = test_data.values.reshape(-1,28,28,1)","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:00.393671Z","iopub.execute_input":"2022-07-14T02:36:00.394040Z","iopub.status.idle":"2022-07-14T02:36:00.402511Z","shell.execute_reply.started":"2022-07-14T02:36:00.394005Z","shell.execute_reply":"2022-07-14T02:36:00.401436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.utils.np_utils import to_categorical \n# 转为one-hot-encoding独热编码\n\nY = to_categorical(Y, num_classes = 10)","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:00.404472Z","iopub.execute_input":"2022-07-14T02:36:00.404955Z","iopub.status.idle":"2022-07-14T02:36:00.413584Z","shell.execute_reply.started":"2022-07-14T02:36:00.404918Z","shell.execute_reply":"2022-07-14T02:36:00.412592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.imshow(train_data[0][:,:,0])","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:00.419720Z","iopub.execute_input":"2022-07-14T02:36:00.419983Z","iopub.status.idle":"2022-07-14T02:36:00.636492Z","shell.execute_reply.started":"2022-07-14T02:36:00.419958Z","shell.execute_reply":"2022-07-14T02:36:00.635530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nrandom_seed = 2\n\ntrain_data, val_data, Y_train, Y_val = train_test_split(train_data, Y, test_size = 0.1,random_state = random_seed)\n#train_data训练数据，val_data验证数据，Y_train训练结果集，Y_val验证结果集\n","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:00.638192Z","iopub.execute_input":"2022-07-14T02:36:00.638542Z","iopub.status.idle":"2022-07-14T02:36:01.017313Z","shell.execute_reply.started":"2022-07-14T02:36:00.638506Z","shell.execute_reply":"2022-07-14T02:36:01.016169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(train_data[0][:,:,0])","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:01.018962Z","iopub.execute_input":"2022-07-14T02:36:01.019497Z","iopub.status.idle":"2022-07-14T02:36:01.239588Z","shell.execute_reply.started":"2022-07-14T02:36:01.019457Z","shell.execute_reply":"2022-07-14T02:36:01.238657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPool2D, Dropout, Flatten, Dense\n\nmodel = Sequential()\n\nmodel.add(Conv2D(filters = 32, kernel_size = (5,5), padding = 'Same', activation = 'relu', input_shape = (28,28,1)))\nmodel.add(Conv2D(filters = 32, kernel_size = (5,5), padding = 'Same', activation = 'relu'))\nmodel.add(MaxPool2D(pool_size = (2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(filters = 64, kernel_size = (5,5), padding = 'Same', activation = 'relu'))\nmodel.add(Conv2D(filters = 64, kernel_size = (5,5), padding = 'Same', activation = 'relu'))\nmodel.add(MaxPool2D(pool_size = (2,2), strides = (2,2)))\nmodel.add(Dropout(0.25))\n\n\n\nmodel.add(Flatten())\nmodel.add(Dense(256, activation = 'relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(10,activation = 'softmax'))","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:01.241234Z","iopub.execute_input":"2022-07-14T02:36:01.241595Z","iopub.status.idle":"2022-07-14T02:36:03.773748Z","shell.execute_reply.started":"2022-07-14T02:36:01.241558Z","shell.execute_reply":"2022-07-14T02:36:03.772769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#from keras.optimizers会import失败，需要指定tensorflow版本的keras\nfrom tensorflow.keras.optimizers import RMSprop \n\n#优化器\noptimizer = RMSprop(learning_rate = 0.001, rho = 0.9, epsilon = 1e-08, decay = 0.0)\n\n#可使用SGD\nfrom tensorflow.keras.optimizers import SGD\n\n#optimizer = SGD(learning_rate = 0.01, momentum = 0.0, nesterov = False, decay = 0.0)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:03.775018Z","iopub.execute_input":"2022-07-14T02:36:03.775826Z","iopub.status.idle":"2022-07-14T02:36:03.783005Z","shell.execute_reply.started":"2022-07-14T02:36:03.775787Z","shell.execute_reply":"2022-07-14T02:36:03.781681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer = optimizer, loss = \"categorical_crossentropy\", metrics=[\"accuracy\"])","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:03.784690Z","iopub.execute_input":"2022-07-14T02:36:03.785106Z","iopub.status.idle":"2022-07-14T02:36:03.802882Z","shell.execute_reply.started":"2022-07-14T02:36:03.785057Z","shell.execute_reply":"2022-07-14T02:36:03.801752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.callbacks import ReduceLROnPlateau\n#动态调整LR\n\nlearning_rate_reduction = ReduceLROnPlateau(monitor = 'val_acc',\n                                           patience=3,\n                                           verbose=1,\n                                           factor=0.5,\n                                           min_lr=0.00001)","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:03.804418Z","iopub.execute_input":"2022-07-14T02:36:03.804819Z","iopub.status.idle":"2022-07-14T02:36:03.812310Z","shell.execute_reply.started":"2022-07-14T02:36:03.804782Z","shell.execute_reply":"2022-07-14T02:36:03.811279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 70#步长\nbatch_size = 86 #数据簇大小","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:03.814001Z","iopub.execute_input":"2022-07-14T02:36:03.814712Z","iopub.status.idle":"2022-07-14T02:36:03.819740Z","shell.execute_reply.started":"2022-07-14T02:36:03.814674Z","shell.execute_reply":"2022-07-14T02:36:03.818370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"数据增强","metadata":{}},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n#数据增强\ndatagen = ImageDataGenerator(\n        featurewise_center = False,\n        samplewise_center=False,\n        featurewise_std_normalization=False,\n        samplewise_std_normalization=False,\n        zca_whitening=False,\n        #zca_epsilon=1e-6, \n        rotation_range=10,\n        #width_shift_range=0., height_shift_range=0., brightness_range=None, shear_range=0., \n        zoom_range=0.1, \n        #channel_shift_range=0., fill_mode='nearest', cval=0., horizontal_flip=False, vertical_flip=False, rescale=None, preprocessing_function=None, data_format=None, validation_split=0.0, dtype=None\n        width_shift_range = 0.1,\n        height_shift_range = 0.1,\n        horizontal_flip=False,\n        vertical_flip=False)\ndatagen.fit(train_data)","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:03.821495Z","iopub.execute_input":"2022-07-14T02:36:03.822720Z","iopub.status.idle":"2022-07-14T02:36:03.925584Z","shell.execute_reply.started":"2022-07-14T02:36:03.822682Z","shell.execute_reply":"2022-07-14T02:36:03.924564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(datagen.flow(train_data, Y_train, batch_size= batch_size),\n                             epochs = epochs,\n                             validation_data = (val_data, Y_val),\n                             verbose = 2,\n                             steps_per_epoch = train_data.shape[0] // batch_size,\n                             callbacks = [learning_rate_reduction])","metadata":{"execution":{"iopub.status.busy":"2022-07-14T02:36:03.927103Z","iopub.execute_input":"2022-07-14T02:36:03.927717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#训练和验证的数据曲线\n#epoch为1时没有图像显示\n\nfig, ax = plt.subplots(2,1)\nax[0].plot(history.history['loss'], color = 'b', label = \"Training loss\")\nax[0].plot(history.history['val_loss'], color = 'r', label = \"Validation loss\", axes = ax[0])\nlegend = ax[0].legend(loc='best', shadow=True)\n\nax[1].plot(history.history['accuracy'], color='b', label=\"Training Accuracy\")\nax[1].plot(history.history['val_accuracy'], color='r',label=\"Validation Accuracy\")\nlegend = ax[1].legend(loc='best', shadow=True)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfrom sklearn.metrics import confusion_matrix\nimport matplotlib.image as mpimg\nimport itertools\n\ndef plot_confusion_matrix(cm, classes,\n                          normalize=False,\n                          title='Confusion matrix',\n                          cmap=plt.cm.Blues):\n    \"\"\"\n    This function prints and plots the confusion matrix.\n    Normalization can be applied by setting `normalize=True`.\n    \"\"\"\n    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n    plt.title(title)\n    plt.colorbar()\n    tick_marks = np.arange(len(classes))\n    plt.xticks(tick_marks, classes, rotation=45)\n    plt.yticks(tick_marks, classes)\n\n    if normalize:\n        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n\n    thresh = cm.max() / 2.\n    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n        plt.text(j, i, cm[i, j],\n                 horizontalalignment=\"center\",\n                 color=\"white\" if cm[i, j] > thresh else \"black\")\n\n    plt.tight_layout()\n    plt.ylabel('True label')\n    plt.xlabel('Predicted label')\n\n# Predict the values from the validation dataset\nY_pred = model.predict(val_data)\n# Convert predictions classes to one hot vectors \nY_pred_classes = np.argmax(Y_pred,axis = 1) \n# Convert validation observations to one hot vectors\nY_true = np.argmax(Y_val,axis = 1) \n# compute the confusion matrix\nconfusion_mtx = confusion_matrix(Y_true, Y_pred_classes) \n# plot the confusion matrix\nplot_confusion_matrix(confusion_mtx, classes = range(10)) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#实际预测\nres = model.predict(test_data)\nres = np.argmax(res, axis = 1)\nres = pd.Series(res,name = 'Label')\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#保存结果\nsubmission = pd.concat([pd.Series(range(1,28001),name = 'ImageId'), res], axis = 1)\nsubmission.to_csv('submission.csv', index = False)\nprint('save!')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"keras.utils.plot_model(model, to_file='model.png', show_shapes=False, show_layer_names=True, rankdir='TB', expand_nested=False, dpi=96)","metadata":{}},{"cell_type":"code","source":"#画出model结构图\nfrom keras.utils.vis_utils import plot_model\nplot_model(model, to_file='model.png', show_shapes=False, show_layer_names=True, rankdir='TB', expand_nested=False, dpi=96)\nprint('finish')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}