{"cells":[{"metadata":{"_uuid":"4c3f3d35888564d368f7ec68edef5e54426a0c7b"},"cell_type":"markdown","source":"深度学习区分猫狗图片程序"},{"metadata":{"trusted":true,"_uuid":"307ad27f8b36d803d4378e627dc4477e76102483"},"cell_type":"code","source":"import cv2 # 机器视觉库，安装请用pip3 install opencv-python\nimport numpy as np # 数值计算库\nimport os # 系统库\nfrom random import shuffle # 随机数据库 \nfrom tqdm import tqdm # 输出进度库\nimport matplotlib.pyplot as plt # 常用画图库","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"05874c17b3f6134f98d0c9ec3c1bc23ad4080ee0"},"cell_type":"code","source":"train_dir = '../input/train/'\ntest_dir = '../input/test/'\nimg_size = 50\n# learning rate\nlr = 1e-3","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"06c3ad57d5307c8b69ea102933d7194dd9506a22"},"cell_type":"markdown","source":"将label变成每个类别的概率（类似于哑变量）"},{"metadata":{"trusted":true,"_uuid":"d0531644c1668bab97c098aabd147a391c066621"},"cell_type":"code","source":"def label_img(img):\n    # img: cat.0.jpg\n    word_label = img.split('.')[-3]\n    if word_label == 'cat': return [1,0]\n    elif word_label == 'dog': return [0,1]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e33f66d1a7c85f913a66e7356f3f96ea39908abc"},"cell_type":"markdown","source":"处理训练数据，大约需要30秒"},{"metadata":{"trusted":true,"_uuid":"671f68d2d3dfc4d1593885f1c504da762fe24914"},"cell_type":"code","source":"def create_train_data():\n    training_data = []\n    #tqdm 输出进度条\n    for img in tqdm(os.listdir(train_dir)):\n        if (not img.endswith('.jpg')):\n            continue\n        # label_img function return either [1, 0] OR [0, 1] 的one hot encoding type的label\n        label = label_img(img)\n        path = os.path.join(train_dir, img)\n        img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)  # IMREAD_GRAYSCALE 读入灰度图\n        img = cv2.resize(img, (img_size, img_size) )  # 将图片变成统一大小 img_size = 50 i.e.50 * 50\n        training_data.append([np.array(img), np.array(label)])\n    shuffle(training_data)\n    return training_data\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0351c00c482b010b42ed2fb56e836323bf95dfd6"},"cell_type":"code","source":"train_data = create_train_data()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"631050b1a95d387fcb5a2fb3ad483c787a18e811"},"cell_type":"code","source":"train_data[:2]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f6336e5839a9d820eac582eb1714216ff2b1e919"},"cell_type":"code","source":"train_data[1][0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f1340381b72569d605a1ea9cdca7a831814913a1"},"cell_type":"code","source":"train_data[1][1]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e518a9e73945e02b9b01b47127ba212a067600cb"},"cell_type":"markdown","source":"处理测试数据，注意没有label信息"},{"metadata":{"trusted":true,"_uuid":"b190e78465bf52602e495d488c963b09e8545607"},"cell_type":"code","source":"# diff from create_train_data functin, there is no lable to be added to testing_data array\ndef process_test_data():\n    testing_data = []\n    for img in tqdm(os.listdir(test_dir)):\n        if (not img.endswith('.jpg')):\n            continue\n        path = os.path.join(test_dir,img)\n        img_num = img.split('.')[0]\n        img = cv2.imread(path,cv2.IMREAD_GRAYSCALE)\n        img = cv2.resize(img, (img_size, img_size))\n        # different from create_train_data function, for each image, you add img_num\n        testing_data.append([np.array(img), img_num])\n        \n    shuffle(testing_data)\n    return testing_data","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"622e2b2bf35bc886b04d6c1fd21442ea17c30d88"},"cell_type":"markdown","source":"导入基于Tensorflow的高级深度学习库tflearn"},{"metadata":{"trusted":true,"_uuid":"08ffce55ed4f3cee6a208ec786ee48c0e2c1de3a"},"cell_type":"code","source":"import tflearn # 需要安装tensorflow，然后安装tflearn\nfrom tflearn.layers.conv import conv_2d, max_pool_2d  # 2维CNN以及最大采样\nfrom tflearn.layers.core import input_data, dropout, fully_connected # 输入层，dropout，全连接层\nfrom tflearn.layers.estimator import regression # cross entropy层","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a692db64b94fcf02bcf3f376e7899e19ffe81647"},"cell_type":"markdown","source":"注意：如果多次运行不同的网络结构图，每次需要先清空图"},{"metadata":{"trusted":true,"_uuid":"b047ac4375a780745672787a48d505faf5ce674b"},"cell_type":"code","source":"import tensorflow as tf\ntf.reset_default_graph()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9e4c4e28e2f9ed07bd9a0a3ac8096446171f8d27"},"cell_type":"code","source":"# image_size = 50,   shape: 50 * 50 * 1  1通道， None,表示不确定多少样本个数\nconvnet = input_data(shape = [None, img_size, img_size, 1], name = 'input')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5d2ab6fb8f86898eda9e74ce5ee8acdfc7588b6b"},"cell_type":"markdown","source":"3个CNN及2个max pooling层\n\n-- conv_2d(convnet, 32, 5, activation='relu')表示建立32个filter，每一个大小都是5x5xchannel。因为默认使用\"SAME\" padding,加了0使得每个点都可以对应filter左上角\n\n-- max_pool_2d(convnet, 5)表示对于输出的每个5x5的区域求最大值"},{"metadata":{"trusted":true,"_uuid":"a76934319e930e41b4f393647ab8bc90e8ae97e0"},"cell_type":"code","source":"convnet = conv_2d(convnet, 32, 5, activation='relu')\nconvnet = max_pool_2d(convnet, 5)\n\nconvnet = conv_2d(convnet, 64, 5, activation='relu')\nconvnet = max_pool_2d(convnet, 5)\n\nconvnet = conv_2d(convnet, 128, 5, activation='relu')\nconvnet = max_pool_2d(convnet, 5)\n\nconvnet = conv_2d(convnet, 64, 5, activation='relu')\nconvnet = max_pool_2d(convnet, 5)\n\nconvnet = conv_2d(convnet, 32, 5, activation='relu')\nconvnet = max_pool_2d(convnet, 5)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ac674fac4730097aaf3a3390fab727e30cac605e"},"cell_type":"markdown","source":"两个全连接层与预测层"},{"metadata":{"trusted":true,"_uuid":"e5a9cc81f62d17075abb320b34b612838257ddc7"},"cell_type":"code","source":"convnet = fully_connected(convnet, 1024, activation = 'relu')\nconvnet = dropout(convnet, 0.8)\n\n# softmax 输出每一个类别的概率\nconvnet = fully_connected(convnet, 2, activation='softmax')\n# 预测层\nconvnet = regression(convnet, optimizer='adam', learning_rate = lr, loss='categorical_crossentropy', name='targets')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eaa4fa2a104d76058470c559f3e2c3562c6480c7"},"cell_type":"code","source":"model = tflearn.DNN(convnet, tensorboard_dir='log')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c848f9b848d979281271bf801e443f03c52a4f27"},"cell_type":"code","source":"# 从开始 到  导数500 个，（不包含第倒数500个）\ntrain = train_data[:-500]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3358c3922271266a2d67c7bb884aa2304ab67f77"},"cell_type":"code","source":"# 这里的最后500张图片用于validation purpose, 用在training 阶段\ntest = train_data[-500:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"901638898997d6dcd2c922a54462e3ee3b7f0b87"},"cell_type":"code","source":"X = np.array([i[0] for i in train], dtype=np.float64).reshape(-1, img_size, img_size, 1)\nprint(X[:1])\ny = np.array([i[1] for i in train], dtype=np.float64)\nprint(y[:2])\nXtest = np.array([i[0] for i in test], dtype=np.float64).reshape(-1, img_size, img_size, 1)\nytest = np.array([i[1] for i in test], dtype=np.float64)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8aecc36b170d7bacd910d2d5b747bf9633bf3017"},"cell_type":"markdown","source":"在训练集上训练，无GPU大约需要2-3分钟"},{"metadata":{"trusted":true,"_uuid":"435c53676964c67d48d581683eab131436d5750d"},"cell_type":"code","source":"# \"input\" match to: convnet = input_data(shape = [None, img_size, img_size, 1], name = 'input')\n# \"targets\" match to: convnet = regression(convnet, optimizer='adam', learning_rate = lr, loss='categorical_crossentropy', name='targets')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9fbb1de0b19baab856109c759dc77685c669e58b"},"cell_type":"code","source":"model.fit({'input': X}, {'targets': y}, n_epoch=3, validation_set=({'input': Xtest}, {'targets': ytest}), snapshot_step=500, show_metric=True, run_id='model' )","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3a026564231b2a2e40fe4b24763c1c27ca4d9899"},"cell_type":"markdown","source":"读入测试数据，大约需要30秒"},{"metadata":{"trusted":true,"_uuid":"f377ebc20ffea394b746715438642e14494356f5"},"cell_type":"code","source":"test_data = process_test_data()","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"_uuid":"019ea2993dfa572d87dc5df1f6c5a8bbe5b21480"},"cell_type":"markdown","source":"输出测试数据上一些例子的预测"},{"metadata":{"trusted":true,"_uuid":"2dd560a1bf11f3f6d7371346943cfc6dffe2a585"},"cell_type":"code","source":"print(test_data[:2])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"341e4570ed4509b0769d5d5bee2cf6e1118a9d17"},"cell_type":"code","source":"fig = plt.figure()\nfor num,data in enumerate(test_data[:2]):\n    img_num = data[1]\n    print(num) \n    print(img_num)                                 \n    img_data = data[0]\n    print(img_data)\n    ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e746e6fb186764f32c96bc507a221cbd16134a22"},"cell_type":"markdown","source":"#下面的代码中\n\n**raw_model_out** 每一个是一个二维的， 所以需要raw_model_out[0] 取出实际的model_out\n[[0.1101779 0.8898222]]\n[[0.7930341  0.20696592]]\n[[0.23120794 0.7687921 ]]\n\n\n**model_out**\n[0.1101779 0.8898222]\n[0.7930341  0.20696592]\n[0.23120794 0.7687921 ]\n"},{"metadata":{"trusted":true,"_uuid":"896505187113ef22ad38a8de118820441c50adef"},"cell_type":"code","source":"fig = plt.figure()\nfor num,data in enumerate(test_data[:16]):\n    # data[1]就是testing data里的图片编号\n    img_num = data[1]\n    # data[0] 就是testing data里的实际图片数据 50 * 50 二维数组\n    img_data = data[0]\n    # 4 行， 4 列\n    y = fig.add_subplot(4, 4, num+1)\n    orig = img_data\n    # 每一张图片的size 50 * 50 * 1  只有1个通道的灰度图\n    data = img_data.reshape(img_size, img_size, 1)\n    raw_model_out = model.predict([data])\n    model_out = raw_model_out[0]\n    print(model_out)\n    # cat': return [1,0]\n    # 'dog': return [0,1]\n    # 这里的argmax return 的最大值的index , 所以==1 就是dog\n    if np.argmax(model_out) == 1: \n        label = 'Dog'\n    else: \n        label = 'Cat'\n    # 每个图片就是原始的图片用来验证预测的正确与否\n    y.imshow(orig, cmap='gray')\n    # 每个图片的title就是预测的label\n    plt.title(label)\n    y.axes.get_xaxis().set_visible(False)\n    y.axes.get_yaxis().set_visible(False)\n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"8afff4852e3b5b2df2493a565344d39a496292d6"},"cell_type":"code","source":"","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}