{ "cells": [ { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0123456789+*-%\n" ] } ], "source": [ "from captcha.image import ImageCaptcha\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import random\n", "import glob\n", "\n", "%matplotlib inline\n", "%config InlineBackend.figure_format = 'retina'\n", "\n", "import string\n", "\n", "characters = '0123456789+*-%' # 验证码字符集合\n", "print(characters)\n", "\n", "width, height, n_len, n_class = 100, 50, 6, len(characters) + 1 #图片宽、高,验证码最大长度,分类类别:字符集+1个空值" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ " # 防止 tensorflow 占用所有显存\n", "import tensorflow as tf\n", "import tensorflow.keras.backend as K\n", "\n", "config = tf.ConfigProto()\n", "config.gpu_options.allow_growth=True #True \n", "sess = tf.Session(config=config)\n", "K.set_session(sess)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# 定义 CTC Loss\n", "import tensorflow.keras.backend as K\n", "\n", "def ctc_lambda_func(args):\n", " '''\n", " 定义ctc损失函数\n", " 参数:y_pred:预测值,labels:标签,input_length:lstm tiemstep,label_length:标签长度\n", " '''\n", " y_pred, labels, input_length, label_length = args\n", " return K.ctc_batch_cost(labels, y_pred, input_length, label_length)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# 定义网络\n", "from tensorflow.keras.models import *\n", "from tensorflow.keras.layers import *\n", "\n", "input_tensor = Input((height, width, 3))\n", "x = input_tensor\n", "\n", "for i, n_cnn in enumerate([2, 2, 2, 2]): \n", " for j in range(n_cnn):\n", " x = Conv2D(32*2**min(i, 3), kernel_size=3, padding='same', kernel_initializer='he_uniform')(x) # 32*2**min(i, 3)\n", " x = BatchNormalization()(x)\n", " x = Activation('relu')(x)\n", " x = MaxPooling2D(2 if i < 3 else (2, 1))(x)\n", "\n", "x = Permute((2, 1, 3))(x)\n", "x = TimeDistributed(Flatten())(x)\n", "\n", "rnn_size = 64 # 128\n", "# x = Bidirectional(CuDNNGRU(rnn_size, return_sequences=True))(x)\n", "# x = Bidirectional(CuDNNGRU(rnn_size, return_sequences=True))(x)\n", "x = Bidirectional(GRU(rnn_size, return_sequences=True))(x)\n", "x = Bidirectional(GRU(rnn_size, return_sequences=True))(x)\n", "x = Dense(n_class, activation='softmax')(x)\n", "\n", "base_model = Model(inputs=input_tensor, outputs=x)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "labels = Input(name='the_labels', shape=[n_len], dtype='float32')\n", "input_length = Input(name='input_length', shape=[1], dtype='int64')\n", "label_length = Input(name='label_length', shape=[1], dtype='int64')\n", "loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([x, labels, input_length, label_length])\n", "\n", "model = Model(inputs=[input_tensor, labels, input_length, label_length], outputs=loss_out)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# # 网络结构可视化\n", "# from tensorflow.keras.utils import plot_model\n", "# from IPython.display import Image\n", "\n", "# plot_model(model, to_file='ctc.png', show_shapes=True)\n", "# Image('ctc.png')\n" ] }, { "cell_type": "code", "execution_count": 356, "metadata": {}, "outputs": [], "source": [ "# base_model.summary()" ] }, { "cell_type": "code", "execution_count": 300, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'0-0'" ] }, "execution_count": 300, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def get_random_str(n=3):\n", " '''\n", " 得到随机数字加算术符号的公式\n", " 参数:n:参数长度,只能为3或者5\n", " 返回:公式字符串,如2+3\n", " '''\n", " num = '0123456789'\n", " sign = '+*-%'\n", " random_str = ''\n", " for i in range(n):\n", " if n == 3 and i == 1:\n", " random_str += random.choice(sign)\n", " elif n == 5 and i == 2:\n", " random_str += random.choice(sign)\n", " else:\n", " random_str += random.choice(num)\n", " return random_str\n", "get_random_str(random.choice([3,5]))" ] }, { "cell_type": "code", "execution_count": 298, "metadata": {}, "outputs": [], "source": [ "from PIL import Image, ImageFont, ImageDraw\n", "\n", "def random_color(start, end, opacity=None):\n", " '''\n", " 随机颜色函数,返回指定范围随机颜色值\n", " 参数:start:颜色最低值,end:颜色最高值\n", " '''\n", " red = random.randint(start, end)\n", " green = random.randint(start, end)\n", " blue = random.randint(start, end)\n", " if opacity is None:\n", " return (red, green, blue)\n", " return (red, green, blue, opacity)\n", "def random_xy(width,height): \n", " '''\n", " 随机位置函数,返回指定范围随机位置坐标\n", " 参数:width:图片宽,height:图片高\n", " '''\n", " x = random.randint(0, width)\n", " y = random.randint(0, height)\n", " return x, y\n", " \n", "def generate_image(random_str, width=80, height=30):\n", " '''\n", " 随机生成验证码,从四种字体随机抽取一种生成文字,加随机线干扰和点干扰\n", " 参数:random_str:要生成验证码的文字\n", " 返回:验证码图片\n", " '''\n", " image = Image.new(mode='RGB', size=(width, height), color=(255,255,255))\n", " fonts = ['/usr/share/fonts/WindowsFonts/fonts/ariali.ttf', '/usr/share/fonts/WindowsFonts/fonts/simhei.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/constanb.ttf', '/usr/share/fonts/WindowsFonts/fonts/calibri.ttf']\n", " font = ImageFont.truetype(font=random.choice(fonts), size=random.randint(20,23))\n", " draw = ImageDraw.Draw(image) \n", " for _ in range(random.randint(2, 5)):\n", " draw.line(xy=(random_xy(width,height),random_xy(width,height)),fill=random_color(0, 0))\n", " for _ in range(random.randint(0,50)):\n", " draw.point(xy=(random_xy(width,height)),fill=random_color(0, 0))\n", "# draw.text(xy=(random.randint(0,10),random.randint(0,2)),text= random_str, fill=text_fill, font=font)\n", "# len_t = len(random_str)\n", "# for i in range(len_t):\n", "# draw.text(xy=(random.randint(0,2)+i*int(width/len_t+2),random.randint(2,4)),text= random_str[i], \n", "# fill=random_color(0,0,opacity=0), font=font)\n", "\n", " draw.text(xy=(random.randint(0,4),random.randint(2,5)),text= random_str, \n", " fill=random_color(0,0,opacity=0), font=font)\n", " \n", " return image.resize((100,50), Image.BILINEAR)\n" ] }, { "cell_type": "code", "execution_count": 299, "metadata": {}, "outputs": [], "source": [ "# 重组验证码\n", "\n", "def rebuild_arithmetic():\n", " '''\n", " 从切割单个数字和算术符号的列表随机抽取组合为公式,digit_path:数字路径,arith_path:算术符号路径\n", " 重组公式如:1+2= , 15*32, 等号随机给,大部分有等号\n", " 返回:重组并加随机干扰的图片\n", " '''\n", " digit_path = [r'suanshu-pic/zeros/*.jpg',r'suanshu-pic/one/*.jpg',r'suanshu-pic/two/*.jpg',r'suanshu-pic/three/*.jpg',r'suanshu-pic/four/*.jpg',\n", " r'suanshu-pic/five/*.jpg',r'suanshu-pic/six/*.jpg',r'suanshu-pic/seven/*.jpg',r'suanshu-pic/eight/*.jpg',r'suanshu-pic/nine/*.jpg']\n", " arith_path = [r'suanshu-pic/add/*.jpg',r'suanshu-pic/sub/*.jpg',r'suanshu-pic/mul/*.jpg']\n", "\n", " new_img = Image.new(mode='RGB', size=(100,40), color=(255,255,255))\n", "\n", " x = random.randint(2, 20)\n", " y = random.randint(2, 15)\n", " label = []\n", " sign = {0:'+',1:'-',2:'*'}\n", " for i in range(3):\n", " if i == 1: # 中间是符号 + - * \n", " num = random.randint(0, 2)\n", " img = Image.open(random.choice(glob.glob(arith_path[num])))\n", " label.append(sign[num])\n", " else:\n", " num = random.randint(0, 9)\n", " img = Image.open(random.choice(glob.glob(digit_path[num])))\n", " label.append(str(num)) \n", " w, h = img.size\n", " new_img.paste(img,(x, y))\n", " x += w +random.randint(0, 3)\n", " if random.randint(0,9) < 6:\n", " img = Image.open(r'suanshu-pic/equal.jpg')\n", " new_img.paste(img,(x, y))\n", " label = ''.join(label)\n", " draw = ImageDraw.Draw(new_img) \n", " width, height = new_img.size\n", " for _ in range(random.randint(2, 5)):\n", " draw.line(xy=(random_xy(width, height),random_xy(width, height)),fill=(0, 0, 0))\n", " for _ in range(random.randint(20, 50)):\n", " draw.point(xy=(random_xy(width, height)),fill=(0, 0, 0))\n", " return new_img.resize((100,50), Image.BILINEAR), label" ] }, { "cell_type": "code", "execution_count": 301, "metadata": {}, "outputs": [], "source": [ "# 定义数据生成器\n", "from tensorflow.keras.utils import Sequence\n", "\n", "class CaptchaSequence(Sequence):\n", " '''\n", " 继承Sequence的数据生成类,方便调用多CPU,加快生成训练及测试数据\n", " 参数:self.characters:验证码字符集合,self.batch_size:每批次样本数,self.steps:生成多少批数据,self.n_len:验证码长度,\n", " self.width:图片宽度,self.height:图片高度,self.input_length:lstm time step长度,self.label_length:标签长度\n", " 返回:array类型训练或测试数据 \n", " \n", " '''\n", " def __init__(self, characters, batch_size, steps, n_len=6, width=100, height=50, \n", " input_length=12, label_length=6): # width=128, height=64, input_length=16, label_length=4\n", " self.characters = characters\n", " self.batch_size = batch_size\n", " self.steps = steps\n", " self.n_len = n_len\n", " self.width = width\n", " self.height = height\n", " self.input_length = input_length\n", " self.label_length = label_length\n", "# self.label_length = self.n_len\n", " self.n_class = len(characters)\n", " self.generator = ImageCaptcha(width=width, height=height)\n", " \n", " def __len__(self):\n", " return self.steps\n", "\n", " def __getitem__(self, idx):\n", " X = np.zeros((self.batch_size, self.height, self.width, 3), dtype=np.float32)\n", " y = np.zeros((self.batch_size, self.n_len), dtype=np.uint8)\n", " input_length = np.ones(self.batch_size)*self.input_length\n", " label_length = np.ones(self.batch_size)*self.label_length \n", " for i in range(self.batch_size): \n", " if i % 2 == 0:\n", " image, random_str = rebuild_arithmetic() \n", " elif i % 2 == 1: \n", " random_str = get_random_str(random.choice([3,5]))\n", " image = generate_image(random_str, 80, 30) \n", "# elif i % 3 == 2:\n", "# random_str = get_random_str(random.choice([3,5]))\n", "# image = self.generator.generate_image(random_str) \n", " X[i] = np.array(image)/255.0\n", " label = [self.characters.find(x) for x in random_str]\n", " if len(random_str) < self.n_len:\n", " label += [self.n_class]*(self.n_len-len(random_str)) \n", " y[i] = label\n", "\n", " return [X, y, input_length, label_length], np.ones(self.batch_size)\n" ] }, { "cell_type": "code", "execution_count": 317, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Text(0.5, 1.0, '17+15')" ] }, "execution_count": 317, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "image/png": { "height": 213, "width": 370 }, "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# 测试生成器\n", "data = CaptchaSequence(characters, batch_size=10, steps=5)\n", "[X_test, y_test, input_length, label_length], _ = data[3]\n", "idx = 1\n", "plt.imshow(X_test[idx])\n", "plt.title(''.join([characters[x] for x in y_test[idx] if x < len(characters)]))\n", "# print(input_length, label_length)\n", "# print(y_test)\n", "# print(X_test.shape)\n", "# print(n_class)" ] }, { "cell_type": "code", "execution_count": 233, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1, 30, 80, 3)\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 233, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "image/png": { "height": 158, "width": 370 }, "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# 从现有图片生成测试数据\n", "def get_data(img_path):\n", " img = Image.open(img_path)\n", "# img = img.crop((0, height-25, width, height))\n", " w, h = img.size\n", " data = np.zeros((1,h, w, 3))\n", " data[0] = np.array(img)/255.0\n", " return data\n", "img_path = '../FileInfo/ffc510f4-f977-11e9-b970-408d5cd36814_5802.jpg'\n", "\n", "data = get_data(img_path)\n", "print(data.shape)\n", "plt.imshow(data[0])" ] }, { "cell_type": "code", "execution_count": 318, "metadata": {}, "outputs": [], "source": [ "# 准确率回调函数\n", "from tqdm import tqdm\n", "\n", "def evaluate(model, batch_size=128, steps=1):\n", " '''\n", " 准确率验证函数,每批次的验证码长度必须一致\n", " '''\n", " batch_acc = 0\n", " valid_data = CaptchaSequence(characters, batch_size, steps)\n", " for i in range(len(valid_data)):\n", " [X_test, y_test, _, _], _ = valid_data[i]\n", " y_pred = base_model.predict(X_test)\n", " shape = y_pred.shape\n", " # out = K.get_value(K.ctc_decode(y_pred, input_length=np.ones(shape[0])*shape[1],)[0][0])[:, :4]\n", " out = K.get_value(K.ctc_decode(y_pred, input_length=np.ones(shape[0])*shape[1],)[0][0])[:, :]\n", " # print(y_test)\n", " # print(type(y_test))\n", " # print(y_test[y_test<10, axis=1])\n", " # print(out)\n", " if out.shape[1] >= 4:\n", " batch_acc += (y_test[:,:out.shape[1]] == out).all(axis=1).mean()\n", " return batch_acc / steps" ] }, { "cell_type": "code", "execution_count": 357, "metadata": {}, "outputs": [], "source": [ "# model.load_weights('digit4to6_ctc_best2.h5')\n", "# evaluate(base_model,batch_size=1, steps=10)" ] }, { "cell_type": "code", "execution_count": 319, "metadata": {}, "outputs": [], "source": [ "from tensorflow.keras.callbacks import Callback\n", "\n", "class Evaluate(Callback):\n", " '''\n", " 验证准确率的类\n", " '''\n", " def __init__(self):\n", " self.accs = []\n", " \n", " def on_epoch_end(self, epoch, logs=None):\n", " logs = logs or {}\n", " acc = evaluate(base_model, batch_size=128) # evaluate(base_model)\n", " logs['val_acc'] = acc\n", " self.accs.append(acc)\n", " print('\\nacc%.4f'%acc)\n" ] }, { "cell_type": "code", "execution_count": 320, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.9427\n", "acc0.2109\n", "1000/1000 [==============================] - 176s 176ms/step - loss: 0.9418 - val_loss: 0.1676\n", "Epoch 2/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0136\n", "acc0.2266\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 0.0136 - val_loss: 0.0195\n", "Epoch 3/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0079\n", "acc0.2812\n", "1000/1000 [==============================] - 161s 161ms/step - loss: 0.0079 - val_loss: 0.0143\n", "Epoch 4/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0051\n", "acc0.2109\n", "1000/1000 [==============================] - 169s 169ms/step - loss: 0.0051 - val_loss: 0.0076\n", "Epoch 5/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0039\n", "acc0.2188\n", "1000/1000 [==============================] - 164s 164ms/step - loss: 0.0038 - val_loss: 0.0125\n", "Epoch 6/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0026\n", "acc0.2266\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 0.0026 - val_loss: 5.9556e-04\n", "Epoch 7/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0017\n", "acc0.2734\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 0.0017 - val_loss: 0.0011\n", "Epoch 8/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0020\n", "acc0.2578\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 0.0020 - val_loss: 5.6889e-04\n", "Epoch 9/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0010\n", "acc0.2812\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 0.0010 - val_loss: 3.3886e-04\n", "Epoch 10/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0013\n", "acc0.2656\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 0.0013 - val_loss: 0.0011\n", "Epoch 11/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0011\n", "acc0.2812\n", "1000/1000 [==============================] - 142s 142ms/step - loss: 0.0011 - val_loss: 6.8706e-04\n", "Epoch 12/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0018\n", "acc0.1797\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 0.0018 - val_loss: 0.0023\n", "Epoch 13/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0015\n", "acc0.2812\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 0.0015 - val_loss: 3.2869e-04\n", "Epoch 14/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 9.4742e-04\n", "acc0.2344\n", "1000/1000 [==============================] - 173s 173ms/step - loss: 9.4670e-04 - val_loss: 0.0031\n", "Epoch 15/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 7.2305e-04\n", "acc0.2500\n", "1000/1000 [==============================] - 162s 162ms/step - loss: 7.2263e-04 - val_loss: 0.0011\n", "Epoch 16/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 5.9020e-04\n", "acc0.2344\n", "1000/1000 [==============================] - 156s 156ms/step - loss: 5.8988e-04 - val_loss: 0.0672\n", "Epoch 17/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0016\n", "acc0.2422\n", "1000/1000 [==============================] - 160s 160ms/step - loss: 0.0016 - val_loss: 6.5228e-04\n", "Epoch 18/200\n", " 999/1000 [============================>.] - ETA: 0s - loss: 7.7943e-04\n", "acc0.2422\n", "1000/1000 [==============================] - 158s 158ms/step - loss: 7.7944e-04 - val_loss: 0.3539\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 320, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 模型训练\n", "from tensorflow.keras.callbacks import EarlyStopping, CSVLogger, ModelCheckpoint\n", "from tensorflow.keras.optimizers import *\n", "# model.load_weights('digit4to6_ctc_best.h5')\n", "\n", "train_data = CaptchaSequence(characters, batch_size=128, steps=1000) # (characters, batch_size=128, steps=1000)\n", "valid_data = CaptchaSequence(characters, batch_size=128, steps=100) # (characters, batch_size=128, steps=100)\n", "# callbacks = [EarlyStopping(patience=5), Evaluate(), \n", "# CSVLogger('ctc.csv'), ModelCheckpoint('ctc_best.h5', save_best_only=True)]\n", "callbacks = [EarlyStopping(patience=5),Evaluate(),ModelCheckpoint('gru_arith_ctc_best.h5', save_best_only=True)]\n", "model.compile(loss={'ctc': lambda y_true, y_pred: y_pred}, optimizer=Adam(1e-3, amsgrad=True))\n", "# model.fit_generator(train_data, epochs=100, validation_data=valid_data,\n", "# callbacks=callbacks)\n", "model.fit_generator(train_data, epochs=200, validation_data=valid_data, workers=4, use_multiprocessing=True,\n", " callbacks=callbacks)" ] }, { "cell_type": "code", "execution_count": 321, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/300\n", " 999/1000 [============================>.] - ETA: 0s - loss: 0.0010Epoch 1/300\n", "1000/1000 [==============================] - 184s 184ms/step - loss: 0.0010 - val_loss: 0.0011\n", "Epoch 2/300\n", "1000/1000 [==============================] - 173s 173ms/step - loss: 4.4370e-04 - val_loss: 9.3940e-04\n", "Epoch 3/300\n", "1000/1000 [==============================] - 163s 163ms/step - loss: 6.8171e-04 - val_loss: 9.5907e-04\n", "Epoch 4/300\n", "1000/1000 [==============================] - 157s 157ms/step - loss: 5.4397e-04 - val_loss: 0.0015\n", "Epoch 5/300\n", "1000/1000 [==============================] - 155s 155ms/step - loss: 2.3944e-04 - val_loss: 0.0033\n", "Epoch 6/300\n", "1000/1000 [==============================] - 165s 165ms/step - loss: 5.5229e-04 - val_loss: 5.0570e-04\n", "Epoch 7/300\n", "1000/1000 [==============================] - 171s 171ms/step - loss: 3.1110e-04 - val_loss: 0.0027\n", "Epoch 8/300\n", "1000/1000 [==============================] - 178s 178ms/step - loss: 4.0022e-04 - val_loss: 2.1376e-04\n", "Epoch 9/300\n", "1000/1000 [==============================] - 177s 177ms/step - loss: 6.8041e-04 - val_loss: 1.6716e-04\n", "Epoch 10/300\n", "1000/1000 [==============================] - 161s 161ms/step - loss: 5.2196e-04 - val_loss: 9.7826e-05\n", "Epoch 11/300\n", "1000/1000 [==============================] - 162s 162ms/step - loss: 6.3918e-04 - val_loss: 2.8402e-04\n", "Epoch 12/300\n", "1000/1000 [==============================] - 162s 162ms/step - loss: 3.7629e-04 - val_loss: 1.3803e-04\n", "Epoch 13/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 2.3505e-04 - val_loss: 4.0568e-04\n", "Epoch 14/300\n", "1000/1000 [==============================] - 181s 181ms/step - loss: 1.3462e-04 - val_loss: 5.9084e-05\n", "Epoch 15/300\n", "1000/1000 [==============================] - 176s 176ms/step - loss: 2.3387e-04 - val_loss: 2.1895e-04\n", "Epoch 16/300\n", "1000/1000 [==============================] - 190s 190ms/step - loss: 2.5218e-04 - val_loss: 9.2757e-05\n", "Epoch 17/300\n", "1000/1000 [==============================] - 183s 183ms/step - loss: 5.2463e-04 - val_loss: 1.3608e-04\n", "Epoch 18/300\n", "1000/1000 [==============================] - 178s 178ms/step - loss: 2.9944e-04 - val_loss: 6.0091e-05\n", "Epoch 19/300\n", "1000/1000 [==============================] - 156s 156ms/step - loss: 1.5533e-04 - val_loss: 3.2352e-04\n", "Epoch 20/300\n", "1000/1000 [==============================] - 163s 163ms/step - loss: 3.6777e-04 - val_loss: 4.2887e-04\n", "Epoch 21/300\n", "1000/1000 [==============================] - 167s 167ms/step - loss: 3.6488e-04 - val_loss: 7.7524e-04\n", "Epoch 22/300\n", "1000/1000 [==============================] - 175s 175ms/step - loss: 3.3333e-04 - val_loss: 1.6987e-04\n", "Epoch 23/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 3.2431e-04 - val_loss: 1.1768e-04\n", "Epoch 24/300\n", "1000/1000 [==============================] - 185s 185ms/step - loss: 3.9404e-04 - val_loss: 4.6857e-04\n", "Epoch 25/300\n", "1000/1000 [==============================] - 182s 182ms/step - loss: 8.3339e-05 - val_loss: 4.6738e-05\n", "Epoch 26/300\n", "1000/1000 [==============================] - 168s 168ms/step - loss: 1.9266e-04 - val_loss: 1.5829e-04\n", "Epoch 27/300\n", "1000/1000 [==============================] - 178s 178ms/step - loss: 1.8916e-04 - val_loss: 5.4299e-05\n", "Epoch 28/300\n", "1000/1000 [==============================] - 167s 167ms/step - loss: 2.3964e-04 - val_loss: 9.5259e-05\n", "Epoch 29/300\n", "1000/1000 [==============================] - 163s 163ms/step - loss: 3.6268e-04 - val_loss: 1.3801e-04\n", "Epoch 30/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 1.2757e-04 - val_loss: 6.6196e-04\n", "Epoch 31/300\n", "1000/1000 [==============================] - 175s 175ms/step - loss: 1.3832e-04 - val_loss: 7.6405e-05\n", "Epoch 32/300\n", "1000/1000 [==============================] - 162s 162ms/step - loss: 1.2200e-04 - val_loss: 1.3213e-04\n", "Epoch 33/300\n", "1000/1000 [==============================] - 159s 159ms/step - loss: 4.1099e-04 - val_loss: 2.5198e-04\n", "Epoch 34/300\n", "1000/1000 [==============================] - 154s 154ms/step - loss: 1.6998e-04 - val_loss: 2.2966e-04\n", "Epoch 35/300\n", "1000/1000 [==============================] - 161s 161ms/step - loss: 1.4058e-04 - val_loss: 2.4422e-04\n", "Epoch 36/300\n", "1000/1000 [==============================] - 161s 161ms/step - loss: 3.1122e-04 - val_loss: 3.4327e-04\n", "Epoch 37/300\n", "1000/1000 [==============================] - 157s 157ms/step - loss: 1.5745e-04 - val_loss: 1.4173e-04\n", "Epoch 38/300\n", "1000/1000 [==============================] - 148s 148ms/step - loss: 1.5709e-04 - val_loss: 4.7105e-05\n", "Epoch 39/300\n", "1000/1000 [==============================] - 160s 160ms/step - loss: 9.2497e-05 - val_loss: 3.2583e-04\n", "Epoch 40/300\n", "1000/1000 [==============================] - 158s 158ms/step - loss: 1.3834e-04 - val_loss: 4.1161e-05\n", "Epoch 41/300\n", "1000/1000 [==============================] - 162s 162ms/step - loss: 9.6326e-05 - val_loss: 3.7297e-05\n", "Epoch 42/300\n", "1000/1000 [==============================] - 157s 157ms/step - loss: 1.9520e-04 - val_loss: 5.2532e-05\n", "Epoch 43/300\n", "1000/1000 [==============================] - 165s 165ms/step - loss: 1.0436e-04 - val_loss: 4.0052e-04\n", "Epoch 44/300\n", "1000/1000 [==============================] - 171s 171ms/step - loss: 2.1647e-04 - val_loss: 7.8247e-05\n", "Epoch 45/300\n", "1000/1000 [==============================] - 177s 177ms/step - loss: 8.3890e-05 - val_loss: 3.7885e-05\n", "Epoch 46/300\n", "1000/1000 [==============================] - 176s 176ms/step - loss: 1.4493e-04 - val_loss: 3.5747e-05\n", "Epoch 47/300\n", "1000/1000 [==============================] - 178s 178ms/step - loss: 9.0973e-05 - val_loss: 3.4711e-04\n", "Epoch 48/300\n", "1000/1000 [==============================] - 170s 170ms/step - loss: 3.0677e-04 - val_loss: 4.6180e-04\n", "Epoch 49/300\n", "1000/1000 [==============================] - 180s 180ms/step - loss: 2.3121e-04 - val_loss: 1.8758e-04\n", "Epoch 50/300\n", "1000/1000 [==============================] - 175s 175ms/step - loss: 1.2918e-04 - val_loss: 7.5505e-05\n", "Epoch 51/300\n", "1000/1000 [==============================] - 178s 178ms/step - loss: 1.3547e-04 - val_loss: 3.7440e-05\n", "Epoch 52/300\n", "1000/1000 [==============================] - 179s 179ms/step - loss: 1.0826e-04 - val_loss: 3.2394e-04\n", "Epoch 53/300\n", "1000/1000 [==============================] - 180s 180ms/step - loss: 7.4286e-05 - val_loss: 5.1404e-05\n", "Epoch 54/300\n", "1000/1000 [==============================] - 171s 171ms/step - loss: 5.6809e-05 - val_loss: 3.1994e-05\n", "Epoch 55/300\n", "1000/1000 [==============================] - 178s 178ms/step - loss: 1.0885e-04 - val_loss: 3.4290e-05\n", "Epoch 56/300\n", "1000/1000 [==============================] - 173s 173ms/step - loss: 7.2824e-05 - val_loss: 3.4268e-05\n", "Epoch 57/300\n", "1000/1000 [==============================] - 166s 166ms/step - loss: 2.4168e-04 - val_loss: 3.7692e-04\n", "Epoch 58/300\n", "1000/1000 [==============================] - 169s 169ms/step - loss: 1.6142e-04 - val_loss: 4.4883e-05\n", "Epoch 59/300\n", "1000/1000 [==============================] - 162s 162ms/step - loss: 1.8367e-04 - val_loss: 5.9309e-05\n", "Epoch 60/300\n", "1000/1000 [==============================] - 156s 156ms/step - loss: 3.4699e-04 - val_loss: 7.7271e-05\n", "Epoch 61/300\n", "1000/1000 [==============================] - 149s 149ms/step - loss: 5.5419e-04 - val_loss: 8.6402e-04\n", "Epoch 62/300\n", "1000/1000 [==============================] - 145s 145ms/step - loss: 2.8763e-04 - val_loss: 1.3040e-04\n", "Epoch 63/300\n", "1000/1000 [==============================] - 155s 155ms/step - loss: 2.1555e-04 - val_loss: 5.2719e-05\n", "Epoch 64/300\n", "1000/1000 [==============================] - 147s 147ms/step - loss: 7.0289e-05 - val_loss: 4.6950e-05\n", "Epoch 65/300\n", "1000/1000 [==============================] - 162s 162ms/step - loss: 4.4315e-05 - val_loss: 3.8443e-05\n", "Epoch 66/300\n", "1000/1000 [==============================] - 166s 166ms/step - loss: 8.4561e-05 - val_loss: 4.8664e-05\n", "Epoch 67/300\n", "1000/1000 [==============================] - 173s 173ms/step - loss: 2.6899e-04 - val_loss: 3.3890e-05\n", "Epoch 68/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 1.6665e-04 - val_loss: 4.0894e-04\n", "Epoch 69/300\n", "1000/1000 [==============================] - 174s 174ms/step - loss: 1.2141e-04 - val_loss: 3.1331e-05\n", "Epoch 70/300\n", "1000/1000 [==============================] - 177s 177ms/step - loss: 3.8320e-05 - val_loss: 2.9930e-05\n", "Epoch 71/300\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "1000/1000 [==============================] - 171s 171ms/step - loss: 1.1021e-04 - val_loss: 3.1021e-05\n", "Epoch 72/300\n", "1000/1000 [==============================] - 161s 161ms/step - loss: 4.5388e-05 - val_loss: 3.5852e-05\n", "Epoch 73/300\n", "1000/1000 [==============================] - 160s 160ms/step - loss: 6.1017e-05 - val_loss: 3.3232e-05\n", "Epoch 74/300\n", "1000/1000 [==============================] - 174s 174ms/step - loss: 4.2917e-05 - val_loss: 9.5800e-05\n", "Epoch 75/300\n", "1000/1000 [==============================] - 176s 176ms/step - loss: 9.7602e-05 - val_loss: 3.1698e-04\n", "Epoch 76/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 9.6901e-05 - val_loss: 3.1216e-05\n", "Epoch 77/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 1.1608e-04 - val_loss: 3.0113e-05\n", "Epoch 78/300\n", "1000/1000 [==============================] - 175s 175ms/step - loss: 1.8235e-04 - val_loss: 1.0474e-04\n", "Epoch 79/300\n", "1000/1000 [==============================] - 158s 158ms/step - loss: 6.1711e-05 - val_loss: 3.5870e-05\n", "Epoch 80/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 8.3924e-05 - val_loss: 2.0741e-04\n", "Epoch 81/300\n", "1000/1000 [==============================] - 169s 169ms/step - loss: 1.5350e-04 - val_loss: 8.8937e-05\n", "Epoch 82/300\n", "1000/1000 [==============================] - 177s 177ms/step - loss: 8.6976e-05 - val_loss: 3.3122e-05\n", "Epoch 83/300\n", "1000/1000 [==============================] - 174s 174ms/step - loss: 1.5647e-04 - val_loss: 1.0379e-04\n", "Epoch 84/300\n", "1000/1000 [==============================] - 175s 175ms/step - loss: 9.7875e-05 - val_loss: 3.5524e-05\n", "Epoch 85/300\n", "1000/1000 [==============================] - 183s 183ms/step - loss: 1.3929e-04 - val_loss: 3.1470e-05\n", "Epoch 86/300\n", "1000/1000 [==============================] - 170s 170ms/step - loss: 2.5025e-04 - val_loss: 5.5329e-05\n", "Epoch 87/300\n", "1000/1000 [==============================] - 165s 165ms/step - loss: 1.8495e-04 - val_loss: 1.2958e-04\n", "Epoch 88/300\n", "1000/1000 [==============================] - 178s 178ms/step - loss: 3.6019e-04 - val_loss: 4.2026e-05\n", "Epoch 89/300\n", "1000/1000 [==============================] - 173s 173ms/step - loss: 5.3775e-05 - val_loss: 4.3344e-05\n", "Epoch 90/300\n", "1000/1000 [==============================] - 180s 180ms/step - loss: 1.2285e-04 - val_loss: 2.3234e-04\n", "Epoch 91/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 1.6010e-04 - val_loss: 1.3987e-04\n", "Epoch 92/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 1.0920e-04 - val_loss: 1.1033e-04\n", "Epoch 93/300\n", "1000/1000 [==============================] - 181s 181ms/step - loss: 3.3462e-04 - val_loss: 3.4772e-05\n", "Epoch 94/300\n", "1000/1000 [==============================] - 160s 160ms/step - loss: 1.3313e-04 - val_loss: 3.1804e-05\n", "Epoch 95/300\n", "1000/1000 [==============================] - 158s 158ms/step - loss: 1.4736e-04 - val_loss: 3.4553e-05\n", "Epoch 96/300\n", "1000/1000 [==============================] - 171s 171ms/step - loss: 5.5056e-05 - val_loss: 4.8883e-04\n", "Epoch 97/300\n", "1000/1000 [==============================] - 159s 159ms/step - loss: 5.0346e-05 - val_loss: 3.2770e-04\n", "Epoch 98/300\n", "1000/1000 [==============================] - 179s 179ms/step - loss: 1.9733e-04 - val_loss: 3.3280e-05\n", "Epoch 99/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 3.6886e-04 - val_loss: 6.4667e-05\n", "Epoch 100/300\n", "1000/1000 [==============================] - 175s 175ms/step - loss: 3.8754e-04 - val_loss: 4.4233e-05\n", "Epoch 101/300\n", "1000/1000 [==============================] - 180s 180ms/step - loss: 4.8779e-05 - val_loss: 3.2077e-05\n", "Epoch 102/300\n", "1000/1000 [==============================] - 177s 177ms/step - loss: 5.1411e-05 - val_loss: 4.1752e-05\n", "Epoch 103/300\n", "1000/1000 [==============================] - 169s 169ms/step - loss: 1.2953e-04 - val_loss: 2.6925e-04\n", "Epoch 104/300\n", "1000/1000 [==============================] - 161s 161ms/step - loss: 9.9507e-05 - val_loss: 2.8775e-05\n", "Epoch 105/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 9.9072e-05 - val_loss: 4.1590e-04\n", "Epoch 106/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 1.8427e-04 - val_loss: 3.7007e-05\n", "Epoch 107/300\n", "1000/1000 [==============================] - 173s 173ms/step - loss: 1.1291e-04 - val_loss: 8.8433e-05\n", "Epoch 108/300\n", "1000/1000 [==============================] - 175s 175ms/step - loss: 9.2973e-05 - val_loss: 8.9229e-04\n", "Epoch 109/300\n", "1000/1000 [==============================] - 177s 177ms/step - loss: 1.2863e-04 - val_loss: 2.8170e-05\n", "Epoch 110/300\n", "1000/1000 [==============================] - 167s 167ms/step - loss: 8.3508e-05 - val_loss: 3.6307e-05\n", "Epoch 111/300\n", "1000/1000 [==============================] - 172s 172ms/step - loss: 5.1110e-05 - val_loss: 4.5913e-04\n", "Epoch 112/300\n", "1000/1000 [==============================] - 156s 156ms/step - loss: 3.7461e-05 - val_loss: 6.5356e-05\n", "Epoch 113/300\n", "1000/1000 [==============================] - 145s 145ms/step - loss: 3.9960e-05 - val_loss: 2.6224e-05\n", "Epoch 114/300\n", "1000/1000 [==============================] - 140s 140ms/step - loss: 2.4254e-04 - val_loss: 3.4847e-04\n", "Epoch 115/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.5642e-04 - val_loss: 2.8974e-04\n", "Epoch 116/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 9.1180e-05 - val_loss: 5.2198e-05\n", "Epoch 117/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.1267e-05 - val_loss: 2.9025e-05\n", "Epoch 118/300\n", "1000/1000 [==============================] - 153s 153ms/step - loss: 1.0828e-04 - val_loss: 2.9317e-05\n", "Epoch 119/300\n", "1000/1000 [==============================] - 126s 126ms/step - loss: 5.8368e-05 - val_loss: 4.7935e-05\n", "Epoch 120/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.2962e-05 - val_loss: 1.3537e-04\n", "Epoch 121/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.3945e-04 - val_loss: 2.9896e-05\n", "Epoch 122/300\n", "1000/1000 [==============================] - 130s 130ms/step - loss: 3.7618e-05 - val_loss: 2.7894e-05\n", "Epoch 123/300\n", "1000/1000 [==============================] - 143s 143ms/step - loss: 5.9025e-05 - val_loss: 2.7968e-05\n", "Epoch 124/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.9272e-05 - val_loss: 5.4050e-05\n", "Epoch 125/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.8081e-05 - val_loss: 4.1698e-04\n", "Epoch 126/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.1305e-05 - val_loss: 2.7150e-05\n", "Epoch 127/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 7.7636e-05 - val_loss: 3.2932e-05\n", "Epoch 128/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.0468e-05 - val_loss: 2.9693e-05\n", "Epoch 129/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.7752e-05 - val_loss: 2.4898e-05\n", "Epoch 130/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.3804e-04 - val_loss: 5.5153e-04\n", "Epoch 131/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 9.2868e-05 - val_loss: 8.9384e-05\n", "Epoch 132/300\n", "1000/1000 [==============================] - 157s 157ms/step - loss: 1.4239e-04 - val_loss: 5.3699e-05\n", "Epoch 133/300\n", "1000/1000 [==============================] - 137s 137ms/step - loss: 1.2307e-04 - val_loss: 3.1433e-05\n", "Epoch 134/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.8591e-05 - val_loss: 3.1050e-05\n", "Epoch 135/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 9.6723e-05 - val_loss: 0.0033\n", "Epoch 136/300\n", "1000/1000 [==============================] - 144s 144ms/step - loss: 2.7852e-04 - val_loss: 6.0203e-05\n", "Epoch 137/300\n", "1000/1000 [==============================] - 181s 181ms/step - loss: 6.5643e-05 - val_loss: 2.5927e-05\n", "Epoch 138/300\n", "1000/1000 [==============================] - 153s 153ms/step - loss: 1.6080e-04 - val_loss: 3.5396e-05\n", "Epoch 139/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.0213e-04 - val_loss: 3.1223e-05\n", "Epoch 140/300\n", "1000/1000 [==============================] - 140s 140ms/step - loss: 1.0071e-04 - val_loss: 2.8090e-05\n", "Epoch 141/300\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "1000/1000 [==============================] - 138s 138ms/step - loss: 4.2123e-05 - val_loss: 2.6725e-05\n", "Epoch 142/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 4.9015e-05 - val_loss: 2.4542e-05\n", "Epoch 143/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.0085e-05 - val_loss: 2.4421e-05\n", "Epoch 144/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.7967e-05 - val_loss: 3.4982e-05\n", "Epoch 145/300\n", "1000/1000 [==============================] - 165s 165ms/step - loss: 3.5055e-05 - val_loss: 2.5152e-05\n", "Epoch 146/300\n", "1000/1000 [==============================] - 136s 136ms/step - loss: 6.5832e-05 - val_loss: 2.3406e-05\n", "Epoch 147/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.5528e-04 - val_loss: 1.1426e-04\n", "Epoch 148/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.6842e-05 - val_loss: 3.1539e-05\n", "Epoch 149/300\n", "1000/1000 [==============================] - 147s 147ms/step - loss: 4.2912e-05 - val_loss: 2.7492e-05\n", "Epoch 150/300\n", "1000/1000 [==============================] - 150s 150ms/step - loss: 4.8399e-05 - val_loss: 2.5564e-05\n", "Epoch 151/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 4.2671e-05 - val_loss: 2.4988e-05\n", "Epoch 152/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.8039e-05 - val_loss: 0.0016\n", "Epoch 153/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.5764e-04 - val_loss: 2.6906e-05\n", "Epoch 154/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 7.4150e-05 - val_loss: 5.4701e-05\n", "Epoch 155/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.5514e-04 - val_loss: 3.1671e-05\n", "Epoch 156/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 8.0441e-05 - val_loss: 4.3281e-05\n", "Epoch 157/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.5451e-04 - val_loss: 5.9502e-05\n", "Epoch 158/300\n", "1000/1000 [==============================] - 129s 129ms/step - loss: 3.2877e-05 - val_loss: 3.4722e-05\n", "Epoch 159/300\n", "1000/1000 [==============================] - 158s 158ms/step - loss: 4.2989e-05 - val_loss: 2.4017e-05\n", "Epoch 160/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.0554e-05 - val_loss: 2.5237e-05\n", "Epoch 161/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 8.0248e-05 - val_loss: 2.5662e-05\n", "Epoch 162/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.1530e-04 - val_loss: 2.8266e-05\n", "Epoch 163/300\n", "1000/1000 [==============================] - 128s 128ms/step - loss: 9.9706e-05 - val_loss: 4.4395e-05\n", "Epoch 164/300\n", "1000/1000 [==============================] - 128s 128ms/step - loss: 4.1462e-05 - val_loss: 2.4384e-05\n", "Epoch 165/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.2033e-05 - val_loss: 2.5273e-05\n", "Epoch 166/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 6.0334e-05 - val_loss: 2.8493e-05\n", "Epoch 167/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.9251e-05 - val_loss: 2.3708e-05\n", "Epoch 168/300\n", "1000/1000 [==============================] - 149s 149ms/step - loss: 1.0242e-04 - val_loss: 2.3696e-05\n", "Epoch 169/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.0387e-05 - val_loss: 2.8484e-05\n", "Epoch 170/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.6512e-05 - val_loss: 2.3209e-05\n", "Epoch 171/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 9.3213e-05 - val_loss: 3.1282e-04\n", "Epoch 172/300\n", "1000/1000 [==============================] - 134s 134ms/step - loss: 8.3804e-05 - val_loss: 7.9387e-05\n", "Epoch 173/300\n", "1000/1000 [==============================] - 167s 167ms/step - loss: 1.7059e-04 - val_loss: 7.1748e-05\n", "Epoch 174/300\n", "1000/1000 [==============================] - 141s 141ms/step - loss: 8.8687e-05 - val_loss: 2.5140e-05\n", "Epoch 175/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 6.0447e-05 - val_loss: 9.2774e-05\n", "Epoch 176/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.7725e-05 - val_loss: 2.3224e-05\n", "Epoch 177/300\n", "1000/1000 [==============================] - 159s 159ms/step - loss: 2.5208e-04 - val_loss: 2.9746e-05\n", "Epoch 178/300\n", "1000/1000 [==============================] - 168s 168ms/step - loss: 2.7669e-05 - val_loss: 8.5984e-05\n", "Epoch 179/300\n", "1000/1000 [==============================] - 127s 127ms/step - loss: 1.5266e-04 - val_loss: 2.5076e-05\n", "Epoch 180/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.4059e-05 - val_loss: 2.5982e-05\n", "Epoch 181/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.1466e-05 - val_loss: 3.3464e-05\n", "Epoch 182/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 4.7291e-05 - val_loss: 2.3163e-05\n", "Epoch 183/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.8155e-05 - val_loss: 2.6907e-05\n", "Epoch 184/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.7113e-05 - val_loss: 1.0874e-04\n", "Epoch 185/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.3925e-04 - val_loss: 2.6293e-05\n", "Epoch 186/300\n", "1000/1000 [==============================] - 168s 168ms/step - loss: 1.0306e-04 - val_loss: 2.4072e-05\n", "Epoch 187/300\n", "1000/1000 [==============================] - 169s 169ms/step - loss: 1.0437e-04 - val_loss: 3.1735e-05\n", "Epoch 188/300\n", "1000/1000 [==============================] - 141s 141ms/step - loss: 5.7230e-05 - val_loss: 2.6470e-05\n", "Epoch 189/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.0042e-05 - val_loss: 2.5460e-05\n", "Epoch 190/300\n", "1000/1000 [==============================] - 139s 139ms/step - loss: 1.4401e-04 - val_loss: 2.4421e-05\n", "Epoch 191/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.0075e-05 - val_loss: 3.2414e-05\n", "Epoch 192/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.8825e-05 - val_loss: 2.3407e-05\n", "Epoch 193/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.9825e-05 - val_loss: 8.1957e-05\n", "Epoch 194/300\n", "1000/1000 [==============================] - 138s 138ms/step - loss: 7.4839e-05 - val_loss: 5.9782e-05\n", "Epoch 195/300\n", "1000/1000 [==============================] - 129s 129ms/step - loss: 3.3846e-05 - val_loss: 2.3043e-05\n", "Epoch 196/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.1238e-04 - val_loss: 7.8517e-05\n", "Epoch 197/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.9065e-05 - val_loss: 2.2403e-05\n", "Epoch 198/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.9092e-05 - val_loss: 2.3315e-05\n", "Epoch 199/300\n", "1000/1000 [==============================] - 154s 154ms/step - loss: 8.5752e-05 - val_loss: 5.7268e-05\n", "Epoch 200/300\n", "1000/1000 [==============================] - 137s 137ms/step - loss: 9.2915e-05 - val_loss: 4.9792e-05\n", "Epoch 201/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.9838e-04 - val_loss: 2.9707e-05\n", "Epoch 202/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.3203e-05 - val_loss: 8.2439e-05\n", "Epoch 203/300\n", "1000/1000 [==============================] - 134s 134ms/step - loss: 3.9860e-05 - val_loss: 2.4020e-05\n", "Epoch 204/300\n", "1000/1000 [==============================] - 164s 164ms/step - loss: 1.2506e-04 - val_loss: 2.5859e-05\n", "Epoch 205/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.0104e-04 - val_loss: 2.4345e-04\n", "Epoch 206/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 7.5513e-05 - val_loss: 5.1757e-04\n", "Epoch 207/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.1843e-04 - val_loss: 2.3278e-05\n", "Epoch 208/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.6379e-05 - val_loss: 2.6122e-05\n", "Epoch 209/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 8.5780e-05 - val_loss: 2.2804e-05\n", "Epoch 210/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.3299e-04 - val_loss: 2.2211e-05\n", "Epoch 211/300\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "1000/1000 [==============================] - 124s 124ms/step - loss: 1.2123e-04 - val_loss: 4.4857e-05\n", "Epoch 212/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 7.3492e-05 - val_loss: 3.0071e-05\n", "Epoch 213/300\n", "1000/1000 [==============================] - 174s 174ms/step - loss: 7.6742e-05 - val_loss: 3.0696e-05\n", "Epoch 214/300\n", "1000/1000 [==============================] - 145s 145ms/step - loss: 4.0791e-05 - val_loss: 2.2977e-05\n", "Epoch 215/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 7.4657e-05 - val_loss: 5.3581e-04\n", "Epoch 216/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.0133e-05 - val_loss: 2.3202e-05\n", "Epoch 217/300\n", "1000/1000 [==============================] - 139s 139ms/step - loss: 2.6745e-05 - val_loss: 2.3525e-05\n", "Epoch 218/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.4970e-05 - val_loss: 2.3905e-05\n", "Epoch 219/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 7.8349e-05 - val_loss: 1.6566e-04\n", "Epoch 220/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 8.6617e-05 - val_loss: 2.2260e-05\n", "Epoch 221/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.4473e-05 - val_loss: 2.4769e-05\n", "Epoch 222/300\n", "1000/1000 [==============================] - 133s 133ms/step - loss: 7.3462e-05 - val_loss: 2.5815e-05\n", "Epoch 223/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.3295e-04 - val_loss: 3.5900e-05\n", "Epoch 224/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.2512e-05 - val_loss: 3.1965e-04\n", "Epoch 225/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.8593e-05 - val_loss: 7.2567e-04\n", "Epoch 226/300\n", "1000/1000 [==============================] - 128s 128ms/step - loss: 5.4659e-05 - val_loss: 2.3717e-05\n", "Epoch 227/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.3182e-04 - val_loss: 2.3003e-05\n", "Epoch 228/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 8.4741e-05 - val_loss: 4.0923e-05\n", "Epoch 229/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.5930e-05 - val_loss: 2.1761e-05\n", "Epoch 230/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.0544e-05 - val_loss: 2.4360e-04\n", "Epoch 231/300\n", "1000/1000 [==============================] - 129s 129ms/step - loss: 1.3652e-04 - val_loss: 3.2128e-05\n", "Epoch 232/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 9.7454e-05 - val_loss: 2.4298e-05\n", "Epoch 233/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.7009e-04 - val_loss: 3.1086e-05\n", "Epoch 234/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.9004e-04 - val_loss: 2.5299e-05\n", "Epoch 235/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.1191e-04 - val_loss: 5.2022e-05\n", "Epoch 236/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 5.2859e-05 - val_loss: 2.3706e-05\n", "Epoch 237/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.0258e-04 - val_loss: 3.6201e-05\n", "Epoch 238/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 8.1892e-05 - val_loss: 3.8052e-05\n", "Epoch 239/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 9.4339e-05 - val_loss: 6.5550e-04\n", "Epoch 240/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.0763e-05 - val_loss: 0.0010\n", "Epoch 241/300\n", "1000/1000 [==============================] - 142s 142ms/step - loss: 3.2639e-05 - val_loss: 2.7238e-05\n", "Epoch 242/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.4473e-04 - val_loss: 2.2559e-05\n", "Epoch 243/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 9.5861e-05 - val_loss: 5.0863e-05\n", "Epoch 244/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.8622e-05 - val_loss: 2.3448e-05\n", "Epoch 245/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 6.6597e-05 - val_loss: 2.2746e-05\n", "Epoch 246/300\n", "1000/1000 [==============================] - 131s 131ms/step - loss: 1.4180e-04 - val_loss: 2.2630e-05\n", "Epoch 247/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.0733e-05 - val_loss: 1.0448e-04\n", "Epoch 248/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.5378e-05 - val_loss: 2.2891e-05\n", "Epoch 249/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.2440e-05 - val_loss: 2.8702e-05\n", "Epoch 250/300\n", "1000/1000 [==============================] - 135s 135ms/step - loss: 5.2473e-05 - val_loss: 3.0872e-05\n", "Epoch 251/300\n", "1000/1000 [==============================] - 141s 141ms/step - loss: 4.4375e-05 - val_loss: 2.3633e-05\n", "Epoch 252/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.3862e-05 - val_loss: 6.5543e-05\n", "Epoch 253/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 9.5005e-05 - val_loss: 2.2803e-05\n", "Epoch 254/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.7267e-04 - val_loss: 4.3922e-05\n", "Epoch 255/300\n", "1000/1000 [==============================] - 144s 144ms/step - loss: 5.3349e-05 - val_loss: 2.2527e-05\n", "Epoch 256/300\n", "1000/1000 [==============================] - 132s 132ms/step - loss: 3.0744e-05 - val_loss: 1.3200e-04\n", "Epoch 257/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 5.7999e-05 - val_loss: 2.3560e-05\n", "Epoch 258/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 2.1464e-04 - val_loss: 2.4529e-05\n", "Epoch 259/300\n", "1000/1000 [==============================] - 132s 132ms/step - loss: 3.9503e-05 - val_loss: 2.2766e-05\n", "Epoch 260/300\n", "1000/1000 [==============================] - 147s 147ms/step - loss: 2.9882e-05 - val_loss: 2.4284e-05\n", "Epoch 261/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.3018e-05 - val_loss: 2.2551e-05\n", "Epoch 262/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.4223e-05 - val_loss: 5.1047e-05\n", "Epoch 263/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 5.2349e-05 - val_loss: 2.4248e-05\n", "Epoch 264/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.6777e-05 - val_loss: 3.7698e-05\n", "Epoch 265/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.1822e-04 - val_loss: 2.2366e-05\n", "Epoch 266/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 7.7976e-05 - val_loss: 7.2625e-05\n", "Epoch 267/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 5.8099e-05 - val_loss: 2.2275e-05\n", "Epoch 268/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.6940e-05 - val_loss: 2.3144e-05\n", "Epoch 269/300\n", "1000/1000 [==============================] - 148s 148ms/step - loss: 2.3026e-05 - val_loss: 2.3013e-05\n", "Epoch 270/300\n", "1000/1000 [==============================] - 132s 132ms/step - loss: 8.1201e-05 - val_loss: 2.3175e-05\n", "Epoch 271/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.7847e-05 - val_loss: 1.0042e-04\n", "Epoch 272/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 4.7196e-05 - val_loss: 5.0162e-05\n", "Epoch 273/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.4138e-05 - val_loss: 2.0931e-05\n", "Epoch 274/300\n", "1000/1000 [==============================] - 147s 147ms/step - loss: 1.2727e-04 - val_loss: 2.3975e-05\n", "Epoch 275/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.3176e-04 - val_loss: 2.6250e-05\n", "Epoch 276/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 6.2345e-05 - val_loss: 2.4079e-05\n", "Epoch 277/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.5924e-04 - val_loss: 2.5440e-05\n", "Epoch 278/300\n", "1000/1000 [==============================] - 129s 129ms/step - loss: 1.6868e-04 - val_loss: 9.3653e-05\n", "Epoch 279/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.6890e-05 - val_loss: 3.4722e-05\n", "Epoch 280/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.5087e-05 - val_loss: 2.2017e-05\n", "Epoch 281/300\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "1000/1000 [==============================] - 125s 125ms/step - loss: 7.6902e-05 - val_loss: 2.4241e-05\n", "Epoch 282/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 7.9348e-05 - val_loss: 2.1721e-05\n", "Epoch 283/300\n", "1000/1000 [==============================] - 128s 128ms/step - loss: 6.9615e-05 - val_loss: 2.3567e-05\n", "Epoch 284/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 4.3504e-05 - val_loss: 2.1169e-05\n", "Epoch 285/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 9.8986e-05 - val_loss: 2.2475e-05\n", "Epoch 286/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 9.9155e-05 - val_loss: 2.2234e-05\n", "Epoch 287/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.8084e-05 - val_loss: 2.1673e-05\n", "Epoch 288/300\n", "1000/1000 [==============================] - 131s 131ms/step - loss: 2.8233e-05 - val_loss: 2.1597e-05\n", "Epoch 289/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 1.1044e-04 - val_loss: 3.4037e-05\n", "Epoch 290/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.8889e-05 - val_loss: 2.2750e-05\n", "Epoch 291/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.3660e-05 - val_loss: 2.1579e-05\n", "Epoch 292/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 3.1530e-05 - val_loss: 4.7690e-05\n", "Epoch 293/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 5.1966e-05 - val_loss: 2.3497e-05\n", "Epoch 294/300\n", "1000/1000 [==============================] - 124s 124ms/step - loss: 1.8929e-04 - val_loss: 6.9090e-05\n", "Epoch 295/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 6.8542e-05 - val_loss: 3.7624e-05\n", "Epoch 296/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 2.8019e-05 - val_loss: 2.2603e-05\n", "Epoch 297/300\n", "1000/1000 [==============================] - 126s 126ms/step - loss: 2.4500e-05 - val_loss: 2.3005e-05\n", "Epoch 298/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 4.2151e-05 - val_loss: 2.1834e-05\n", "Epoch 299/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 3.5576e-05 - val_loss: 2.4193e-05\n", "Epoch 300/300\n", "1000/1000 [==============================] - 125s 125ms/step - loss: 7.3954e-05 - val_loss: 2.9173e-05\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 321, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 载入最好的模型使用低一点的学习率继续训练一会\n", "model.load_weights('gru_arith_ctc_best.h5')\n", "\n", "# callbacks = [EarlyStopping(patience=5),\n", "# CSVLogger('ctc.csv', append=True), ModelCheckpoint('ctc_best.h5', save_best_only=True)]\n", "callbacks = [CSVLogger('ctc.csv', append=True), ModelCheckpoint('gru_arith_ctc_best.h5', save_best_only=True)]\n", "\n", "model.compile(loss={'ctc': lambda y_true, y_pred: y_pred}, optimizer=Adam(1e-4, amsgrad=True))\n", "model.fit_generator(train_data, epochs=300, validation_data=valid_data, workers=4, use_multiprocessing=True,\n", " callbacks=callbacks)" ] }, { "cell_type": "code", "execution_count": 338, "metadata": {}, "outputs": [], "source": [ "# 保存中间我们最终需要的模型\n", "# model.load_weights('ctc_best.h5')\n", "base_model.save('gru_arith_base_model.h5') " ] }, { "cell_type": "code", "execution_count": 355, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "总耗时: 0.5865483283996582\n", "172 0\n" ] } ], "source": [ "# 测试模型\n", "characters2 = characters + ' '\n", "import time\n", "import re\n", "\n", "def get_test_data():\n", " '''\n", " 从本地获取验证码图片并生成测试数据\n", " '''\n", " X = []\n", " Y = []\n", " for path in glob.glob('../FileInfo1031/*.jpg'): # Digit5/*.jpg ../FileInfo1031/*.jpg\n", "# print(path)\n", " if '9ca857e4-fbc8-11e9-9bc7-408d5cd36814_1.jpg' in path:\n", " continue\n", " random_str = path.split('_')[-1][:-4] \n", " if random_str.isdigit() and len(random_str) < 3:\n", " img = Image.open(path)\n", " X.append(np.array(img.resize((100,50), Image.BILINEAR))/255.0)\n", " label_idx = [characters.find(x) for x in random_str]\n", " if len(random_str) < n_len:\n", " label_idx += [n_class-1]*(n_len-len(random_str)) \n", " Y.append(label_idx)\n", " return [np.array(X), np.array(Y), np.ones(len(X)), np.ones(len(X))],np.ones(len(X))\n", "\n", "data = [get_test_data()]\n", "\n", "# data = CaptchaSequence(characters, batch_size=128, steps=1)\n", "\n", "pos = neg = 0\n", "t1 = time.time()\n", "for i in range(len(data)): \n", " flag = False\n", " [X_test, y_test, _, _], _ = data[i]\n", " y_pred = base_model.predict(X_test)\n", "# print(y_pred.shape)\n", " out_pre = K.get_value(K.ctc_decode(y_pred, input_length=np.ones(y_pred.shape[0])*y_pred.shape[1])[0][0])[:, :6]\n", "# print(out_pre.shape)\n", "# print(out)\n", " for j in range(out_pre.shape[0]):\n", " out = ''.join([characters[x] for x in out_pre[j]]) \n", " y_true = ''.join([characters[x] for x in y_test[j] if x < len(characters)])\n", "# print(out)\n", "# if out != y_true:\n", " if re.search('\\+|\\-|\\*', out) == None: # 判断输出是否正常\n", " print(y_true)\n", " plt.imshow(X_test[j])\n", " plt.title('pred:' + str(out) + '\\ntrue: ' + str(y_true))\n", " print(out)\n", " break\n", " out = eval(str(out))\n", " \n", " if str(out) != y_true: # 验证错误\n", " plt.imshow(X_test[j])\n", " plt.title('pred:' + str(out) + '\\ntrue: ' + str(y_true))\n", " print('pred:' + str(out) + '\\ntrue: ' + str(y_true))\n", " neg += 1\n", " flag = True\n", "# break\n", "# time.sleep(1)\n", "# argmax = np.argmax(y_pred, axis=2)[j]\n", "# print(list(zip(argmax, ''.join([characters2[x] for x in argmax]))))\n", " else:\n", "# print('pred:' + str(out) + '\\ntrue: ' + str(y_true))\n", " pos += 1 \n", "\n", "# if flag:\n", "# break\n", "t2 = time.time()\n", "print('总耗时:',t2-t1)\n", "print(pos,neg)\n", "# # plt.imshow(X_test[0])\n", "# # plt.title('pred:' + str(out) + '\\ntrue: ' + str(y_true))\n", "\n", "# argmax = np.argmax(y_pred, axis=2)[0]\n", "# list(zip(argmax, ''.join([characters2[x] for x in argmax])))" ] }, { "cell_type": "code", "execution_count": 199, "metadata": {}, "outputs": [], "source": [ "evaluate(base_model,batch_size=128, steps=10)" ] }, { "cell_type": "code", "execution_count": 359, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 359, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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sn27iy++mKamJhYuXMhb3/rWgn38x3/8BzfccEPJ2zp1au6c8Nq1a3t9fc2aNQXbQW7uwre//W2+/e1v89xzz3HPPffwox/9iEsuuYTNmzfzy1/+cvu2Z555JmeeeSabN29myZIlXHfddVx22WX8zd/8DU899RQ77bRTCT/d6FD0ABBC+Gfgu8CTwHExxo2DfGvXr7Cvgryu5zcPtKMY47w+2rYUmNvnG6vHDbRrSZKkMWf8+PG8733v46c//Sl33HEHy5cvp729veDsP8Bzzz3HjBkzenT+Ae65556ytPWwww4D4O677+719YULFwIwd27vXbr99tuP/fbbjw996EPsvPPOfYaWadOmceKJJ3LiiSeSzWa57LLLuPfee3nPe94z8g8xyhW1BCiEcB7wfeBx4G0xxt6jW++e7rztq8b/tZ23fc0RGLkqRwAkSVJl6ioD+sUvfsEvfvELqqure0yynTNnDhs3buTRRx8teP5nP/sZt902mIrukZs/fz4HHHAAixcv5pprril47ZprrmHRokXsv//+HH300QC88MIL/OUvf+mxn02bNtHS0lIwOXjhwoXEGHtsu27dOgAmTJhQzI8yahVtBCCE8AVydf8PA2+PMQ51LaWFnbfvCCFkul1TYDIwH2gE/lyM9vbKScCSJKlCzZ8/n/3224+rr76atrY2Tj755B5LYZ533nncdtttHH300bzvfe9j6tSpPPjggyxevJj3vve9PTrkpRBC4IorruDtb38773//+3n3u9/NgQceyNNPP83111/P5MmT+cUvfkEmkzuP/cgjj3DaaadxxBFHcNBBB7Hbbrvx6quvcsMNN9DW1sYXvvCF7fs+9dRTmTRpEkcddRRz5swhxsiiRYt44IEHmDdvHscff3zJP99oUJQRgBDCv5Hr/C8lV/bTZ+c/hFATQjiwc93/7WKMzwO3A3OAc7q97SJgIvDLkl0DAAwAkiSpop111lm0tbVtv9/dCSecwI033sjBBx/MVVddxc9+9jPq6upYuHAhJ510UtnaeeSRR/LAAw/woQ99iD/96U984xvfYMmSJXzwgx/kgQce4Mgjj9y+7eGHH84Xv/hFqqurufXWW/nmN7/JLbfcwrx587j55pv57Gc/u33br3/96xxxxBEsW7aMSy+9lMsvv5y2tjb+8z//k4ULF/a6PGglCr0NgwxpByGc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\n", "text/plain": [ "
" ] }, "metadata": { "image/png": { "height": 250, "width": 384 }, "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# 展示损失下降图\n", "import pandas as pd\n", "\n", "df = pd.read_csv('ctc.csv')\n", "df[['loss', 'val_loss']].plot()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.0" } }, "nbformat": 4, "nbformat_minor": 2 }