{ "cells": [ { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n" ] } ], "source": [ "from captcha.image import ImageCaptcha\n", "from PIL import Image, ImageFont, ImageDraw\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", "# characters = string.digits + string.ascii_uppercase # 验证码字符集合数字+英文\n", "characters = string.digits + string.ascii_uppercase + string.ascii_lowercase # 验证码字符集合数字+英文\n", "# characters = string.digits # 验证码字符集合\n", "print(characters)\n", "\n", "fonts = ['/usr/share/fonts/WindowsFonts/fonts/ANTQUAB.TTF',\n", "# '/usr/share/fonts/WindowsFonts/fonts/AGENCYR.TTF',\n", " '/usr/share/fonts/WindowsFonts/fonts/ANTQUABI.TTF',\n", " '/usr/share/fonts/WindowsFonts/fonts/ARIALNI.TTF',\n", " '/usr/share/fonts/WindowsFonts/fonts/Candara.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/cambriab.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/Candarai.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/calibri.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/constan.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/constanz.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/kaiu.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/simhei.ttf',\n", "# '/usr/share/fonts/WindowsFonts/fonts/STHUPO.TTF', # 粗体不要\n", "# '/usr/share/fonts/WindowsFonts/fonts/STKAITI.TTF',\n", " '/usr/share/fonts/WindowsFonts/fonts/STZHONGS.TTF']\n", "width, height, n_len, n_class = 200, 70, 6, len(characters) + 1 #图片宽、高,验证码最大长度,分类类别:字符集+1个空值" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "import glob\n", "labels = []\n", "for path in glob.glob('/data/captcha/shensexiansandian/*.jpg')[-3000:]:\n", " label = path.split('_')[0].split('/')[-1].lower()\n", " if len(label) ==4:\n", " labels.append(label) " ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "font: /usr/share/fonts/WindowsFonts/fonts/ARIALNI.TTF\n", "字体颜色 (75, 45, 204)\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "image/png": { "height": 279, "width": 2327 }, "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# base_model.summary()\n", "def get_wavy_line(w = (0, 100),h = (30, 50)):\n", " '''产生波浪线坐标'''\n", " import random\n", " n = 50\n", " x = 0\n", " y = random.randint(h[0],h[1])\n", " flag = random.randint(0,2)\n", " xy = [(x, y)]\n", " while x < w[1]:\n", " temp_y = random.randint(1, 3)\n", " temp_x = random.randint(5, 10)\n", " if flag == 0:\n", " if y + temp_y > h[1]:\n", " y -= temp_y\n", " flag = 1\n", " else:\n", " y += temp_y\n", " else:\n", " if y - temp_y < h[0]:\n", " y += temp_y\n", " flag = 0\n", " else:\n", " y -= temp_y\n", " x = x+temp_x if x+temp_x < w[1] else w[1]\n", " xy.append((x, y))\n", " return xy\n", "\n", "def gen_captcha(text, fig_size=(200,70), fonts=['/usr/share/fonts/WindowsFonts/fonts/ANTQUAB.TTF'],font_color=[(0,0,0)],same_color=1, font_size=(25, 35),offset_hor=5,offset_ver=5, rotate=0,\n", " font_noise=0, line=(0,5), line_width=(1,2), point=(0,500),wavy=(0,0), noise_color=[(200,200,255)], bg=[(255,255,255)]):\n", " '''\n", " text:验证码文本\n", " size:验证码图片宽高\n", " fonts:字体列表,随机选择一个\n", " font_noise: 字体散点干扰,0不加干扰,1加干扰\n", " fill:字体颜色范围\n", " rotate:字体旋转角度\n", " line:干扰线条数范围\n", " point:干扰点数范围\n", " wavy:波浪线数范围\n", " color:干扰线、点 颜色\n", " bg:背景色范围\n", " '''\n", " bg = random.choice(bg)\n", " img = Image.new(mode='RGB', size=fig_size, color=bg) #\n", " draw = ImageDraw.Draw(im=img, mode='RGB') # im, mode=None\n", " font_path = random.choice(fonts)\n", " font = ImageFont.truetype(font_path, size=random.randint(font_size[0], font_size[1])) # font=None, size=10, index=0, encoding=\"\"\n", " print('font:', font_path)\n", " def get_char_img(char,font,font_color,rotate,bg, font_noise=0):\n", " '''\n", " 生成单个字符图片,随机颜色加随机旋转\n", " \n", " '''\n", " w, h = draw.textsize(char, font=font)\n", " im = Image.new('RGB',(w,h), color=bg)\n", " ImageDraw.Draw(im).text((0,0), char, font=font, fill=font_color) \n", " if rotate:\n", " im = im.rotate(random.randint(-rotate, rotate),Image.BILINEAR,expand=1)\n", " im = im.crop(im.getbbox())\n", " if font_noise: \n", " im_draw = ImageDraw.Draw(im)\n", "# for i in range(random.randint(10,100)):\n", " for i in range(random.randint(int(w*h*0.01),int(w*h*0.05))):\n", " im_draw.point(xy=(random.randint(0, w), random.randint(0, h)),fill=bg)\n", " table = []\n", " for i in range(256):\n", " table.append(i * 97) # 5.97\n", " mask = im.convert('L').point(table) \n", " return (im, mask)\n", " \n", " char_color = random.choice(font_color)\n", " print('字体颜色',char_color)\n", " if same_color: \n", " char_imgs = [get_char_img(char, font, font_color=char_color, rotate=rotate, bg=bg, font_noise=font_noise) for char in text]\n", " else:\n", " char_imgs = [get_char_img(char, font, font_color=random.choice(font_color), rotate=rotate, bg=bg, font_noise=font_noise) for char in text] \n", " ws = [img[0].size[0] for img in char_imgs]\n", " hs = [img[0].size[1] for img in char_imgs]\n", " w = max(sum(ws), fig_size[0])\n", " h = max(max(hs), fig_size[1])\n", " if w>fig_size[0] or h>fig_size[1]:\n", " img = img.resize((w+6, h+6), Image.BILINEAR)\n", " draw = ImageDraw.Draw(im=img, mode='RGB') # im, mode=None\n", " fig_size = img.size\n", "\n", " if rotate:\n", " temp_x = random.randint(int((fig_size[0]-sum(ws))/5), int((fig_size[0]-sum(ws))/2+1))\n", " temp_y = random.randint(int((fig_size[1]-hs[0])/8), int((fig_size[1]-hs[0])/2+1))\n", " for i in range(len(char_imgs)):\n", " img.paste(char_imgs[i][0], box=(temp_x, temp_y), mask=char_imgs[i][1]) \n", " new_x = temp_x+ws[i]+random.randint(0, offset_hor)\n", " temp_x = new_x if new_x" ] }, "metadata": { "image/png": { "height": 210, "width": 1151 }, "needs_background": "light" }, "output_type": "display_data" } ], "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", "table = []\n", "for i in range( 256 ):\n", " table.append( i * 1.97 )\n", "\n", "def get_wavy_line(w = (0, 100),h = (30, 50)):\n", " '''产生波浪线坐标'''\n", " import random\n", " n = 50\n", " x = 0\n", " y = random.randint(h[0],h[1])\n", " flag = random.randint(0,2)\n", " xy = [(x, y)]\n", " while x < w[1]:\n", " temp_y = random.randint(1, 3)\n", " temp_x = random.randint(5, 10)\n", " if flag == 0:\n", " if y + temp_y > h[1]:\n", " y -= temp_y\n", " flag = 1\n", " else:\n", " y += temp_y\n", " else:\n", " if y - temp_y < h[0]:\n", " y += temp_y\n", " flag = 0\n", " else:\n", " y -= temp_y\n", " x = x+temp_x if x+temp_x < w[1] else w[1]\n", " xy.append((x, y))\n", " return xy\n", "\n", "def get_wavy_text(n = 5,h = (25, 40)):\n", " import random\n", " y = random.randint(h[0],h[1])\n", " flag = random.randint(0,2)\n", " t_h = []\n", " for i in range(n):\n", " temp_y = random.randint(1, 5)\n", " temp_x = random.randint(20, 38)\n", " if flag == 0:\n", " if y + temp_y > h[1]:\n", " y -= temp_y\n", " flag = 1\n", " else:\n", " y += temp_y\n", " else:\n", " if y - temp_y < h[0]:\n", " y += temp_y\n", " flag = 0\n", " else:\n", " y -= temp_y\n", " t_h.append(y)\n", " return t_h\n", "\n", "def generate_image(chars, background = random_color(255,255), width=200, height=70,char_color = [(213,0,0),(255,214,0),(41,98,255),(0,200,83),(0,0,0)]):\n", " '''\n", " 生成验证码图片\n", " chars:要生成的字符串\n", " background:背景颜色\n", " '''\n", " image = Image.new('RGB', (width, height), color=background)\n", " draw = ImageDraw.Draw(image)\n", " def get_char_img(char,font,color,angle):\n", " '''\n", " 生成单个字符图片,随机颜色加随机旋转\n", " \n", " '''\n", " w, h = draw.textsize(char, font=font)\n", "# w, h = ImageDraw.Draw.textsize(char, font=font)\n", " im = Image.new('RGBA',(w,h), color=background)\n", " ImageDraw.Draw(im).text((0,0), char, font=font, fill=color)\n", " im = im.crop(im.getbbox())\n", " rot = im.rotate(angle,Image.BILINEAR,expand=1)\n", " bg = Image.new('RGBA',rot.size,background)\n", " im = Image.composite(rot, bg, rot)\n", " return im\n", " w_all = random.randint(10,30)\n", " im_list = []\n", " w_list = []\n", " fonts = ['/usr/share/fonts/WindowsFonts/fonts/ANTQUAB.TTF','/usr/share/fonts/WindowsFonts/fonts/cambriab.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/Candarai.ttf','/usr/share/fonts/WindowsFonts/fonts/calibri.ttf']\n", " font = ImageFont.truetype(font=random.choice(fonts) , size=random.randint(33,35))\n", "\n", "# f = '/usr/share/fonts/WindowsFonts/fonts/calibri.ttf' # font=random.choice(fonts)\n", "# font = ImageFont.truetype(font=f , size=random.randint(33,35))\n", " \n", " ch_color = random.choice(char_color+[random_color(0,255)])\n", " max_h = height\n", " for c in chars:\n", "# fonts = ['/usr/share/fonts/WindowsFonts/fonts/ariali.ttf','/usr/share/fonts/WindowsFonts/fonts/arial.ttf',\n", "# '/usr/share/fonts/WindowsFonts/fonts/cambriab.ttf','/usr/share/fonts/WindowsFonts/fonts/verdana.ttf']\n", "# font = ImageFont.truetype(font=random.choice(fonts), size=random.randint(18,25))\n", " char_img = get_char_img(char=c, font=font, color=ch_color, angle=random.randint(-10,10))\n", " w, h = char_img.size\n", " max_h = h if h > max_h else max_h\n", " w_all += random.randint(-4,1) \n", " w_list.append(w_all)\n", " im_list.append(char_img)\n", "# image.paste(char_img, (w_all,random.randint(0,image.size[1]-h)))\n", " w_all += w\n", " w_all = width if w_all < width else w_all\n", "# if w_all > width or max_h>height:\n", " image = Image.new('RGB', (w_all, max_h), color=background)\n", " draw = ImageDraw.Draw(image)\n", " \n", " temp_h = 0\n", " t_h = get_wavy_text(n = 6,h = (10, 30))\n", " for i in range(len(w_list)):\n", "# temp = random.randint(2,5)\n", "# h_img = temp+temp_h if temp+temp_h <30 else temp_h-temp# height-im_list[i].size[1]) if height-im_list[i].size[1]>0 else 0\n", "# # print('h_img', h_img)\n", "# temp_h = h_img\n", " image.paste(im_list[i], (w_list[i], t_h[i]))\n", " \n", " for _ in range(random.randint(1, 1)):\n", " x2 = random.randint(30,50)\n", " x3 = x2 + random.randint(40,80)\n", " y = random.randint(30,50)\n", " draw.line(xy=get_wavy_line(w = (0, 200),h = (30, 50)), fill=ch_color, width=random.randint(1,3))\n", "# draw.line(xy=(((0,y),(x2,random.randint(30,55)),(x3,random.randint(30,55)),(width,random.randint(30,55)))),fill=ch_color,width=3)\n", "# for _ in range(random.randint(500,1050)):\n", "# draw.point(xy=(random_xy(width,height)),fill=random_color(255, 255)) \n", " for _ in range(random.randint(0,650)):\n", " draw.point(xy=(random_xy(width,height)),fill=random_color(10, 255)) \n", "# for _ in range(random.randint(0, 10)):\n", "# draw.line(xy=(random_xy(width, height),random_xy(width, height)), fill=random_color(20, 250), width=random.randint(1,2)) \n", " return image.resize((200,70), Image.NEAREST) \n", "\n", "\n", "img = generate_image('cmftq', width=200, height=70)\n", "img2 = Image.open('FileInfo0508/31c1f481-912a-11ea-b24d-408d5cd36814_cmftq.jpg')\n", "# img2 = Image.open('/data/esa_sdk/gan/english/7cff9614-fbc3-11e9-9bc7-408d5cd36814_73zr.jpg')\n", "img2 = img2.convert('RGB')\n", "print(np.array(img).shape)\n", "print(img2.mode)\n", "# img2 = Image.open('/data/esa_sdk/gan/english/7cff9614-fbc3-11e9-9bc7-408d5cd36814_73zr.jpg') # \n", "\n", "img2 = img2.resize((200,70), Image.NEAREST) # Image.BILINEAR\n", "im = [img, img2]\n", "plt.figure(figsize=(20,10))\n", "for i in range(1,3): \n", " plt.subplot(2,2,i)\n", " plt.imshow(im[i-1])\n", "plt.show()\n", "\n", "# plt.imshow(img2)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(70, 200, 3)\n", "RGB\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "image/png": { "height": 279, "width": 2263 }, "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def gen_captcha(text, size=(200,70), fonts=['/usr/share/fonts/WindowsFonts/fonts/calibri.ttf'],fill=(0,255), rotate=(-30,30),\n", " line=(0,10), point=(0,500), color=(0,255), bg=(255,255,255)):\n", " img = Image.new(mode='RGB', size=size, color=bg) #\n", " draw = ImageDraw.Draw(im=img, mode='RGB') # im, mode=None\n", " font = ImageFont.truetype(random.choice(fonts), size=random.randint(30, 45)) # font=None, size=10, index=0, encoding=\"\"\n", " def get_char_img(char,font,color,angle,bg):\n", " '''\n", " 生成单个字符图片,随机颜色加随机旋转\n", " \n", " '''\n", " w, h = draw.textsize(char, font=font)\n", "# w, h = ImageDraw.Draw.textsize(char, font=font)\n", " im = Image.new('RGBA',(w,h), color=bg)\n", " ImageDraw.Draw(im).text((0,0), char, font=font, fill=color)\n", " im = im.crop(im.getbbox())\n", " rot = im.rotate(angle,Image.BILINEAR,expand=1)\n", " bg = Image.new('RGBA',rot.size,color=bg)\n", " im = Image.composite(rot, bg, rot)\n", " return im\n", " #draw.text(xy=(20,30),\n", " #text=text,\n", " #fill=tuple([random.randint(fill[0], fill[1]) for _ in range(3)]),\n", " #font=font) #xy, text, fill=None, font=None, anchor=None\n", " char_color = tuple([random.randint(fill[0],fill[1]) for _ in range(3)])\n", " char_imgs = [get_char_img(char, font, color=char_color, angle=random.randint(rotate[0], rotate[1]), bg=bg) for char in text]\n", " ws = [img.size[0] for img in char_imgs]\n", " hs = [img.size[1] for img in char_imgs]\n", " w = max(sum(ws), size[0])\n", " h = max(max(hs), size[1])\n", " if w>size[0] or h>size[1]:\n", " img = img.resize((w, h), Image.BILINEAR)\n", " draw = ImageDraw.Draw(im=img, mode='RGB') # im, mode=None\n", " size = img.size\n", "\n", "# assert sum(ws) < size[0]\n", "# assert max(hs) < size[1]\n", " temp_x = random.randint(int((size[0]-sum(ws))/5)-1, int((size[0]-sum(ws))/2))\n", " for i in range(len(char_imgs)):\n", " img.paste(char_imgs[i], box=(temp_x, random.randint(int((size[1]-hs[i])/4-1), int((size[1]-hs[i])/2)))) #im, box=None, mask=None\n", " temp_x += random.randint(int(ws[i]*0.8)-1, int(ws[i]*0.9))\n", "# import copy \n", "# img2 = copy.deepcopy(img)\n", "# draw = ImageDraw.Draw(im=img2, mode='RGB') # im, mode=None \n", " \n", " for i in range(random.randint(line[0], line[1])):\n", " draw.line(xy=([(random.randint(0, size[0]), random.randint(0, size[1])) for _ in range(2)]),\n", " fill=tuple([random.randint(color[0], color[1]) for _ in range(3)]),\n", " width=random.randint(0,2)) # xy, fill=None, width=0\n", " for i in range(random.randint(point[0], point[1])):\n", " draw.point(xy=(random.randint(0, size[0]), random.randint(0, size[1])),\n", " fill=tuple([random.randint(color[0], color[1]) for _ in range(3)])) # xy, fill=None\n", " for _ in range(random.randint(0, 2)):\n", " draw.line(xy=get_wavy_line(w = (0, 200),h = (40, 60)), \n", " fill=tuple([random.randint(color[0], color[1]) for _ in range(3)]), width=random.randint(1,3))\n", " return img.resize((200,70), Image.BILINEAR)\n", "# return img.resize((200,70), Image.BILINEAR), img2.resize((200,70), Image.BILINEAR)\n", "\n", "fonts_list = glob.glob('/usr/share/fonts/WindowsFonts/fonts/*.ttf')\n", "img = gen_captcha('GJBIL', fonts=fonts_list, fill=(0,255), rotate=(-20,20),\n", " line=(0,20), point=(0,500), color=(0,255), bg=tuple([random.randint(0,255) for _ in range(3)]))\n", "img2 = Image.open('FileInfo0508/31c1f481-912a-11ea-b24d-408d5cd36814_cmftq.jpg')\n", "# img2 = Image.open('/data/esa_sdk/gan/english/7cff9614-fbc3-11e9-9bc7-408d5cd36814_73zr.jpg')\n", "img2 = img2.convert('RGB')\n", "print(np.array(img).shape)\n", "print(img2.mode)\n", "# img2 = Image.open('/data/esa_sdk/gan/english/7cff9614-fbc3-11e9-9bc7-408d5cd36814_73zr.jpg') # \n", "img2 = img2.resize((200,70), Image.BILINEAR) # Image.BILINEAR\n", "\n", "# img, img2 = gen_captcha('GJBIL', fonts=fonts_list, fill=(0,255), rotate=(-20,20),\n", "# line=(0,20), point=(0,500), color=(0,255), bg=tuple([random.randint(0,255) for _ in range(3)]))\n", "\n", "im = [img, img2]\n", "plt.figure(figsize=(50,10))\n", "for i in range(1,3): \n", " plt.subplot(2,2,i)\n", " plt.imshow(im[i-1])\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'9TCL'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 重组验证码\n", "def rebuild_img(path):\n", " '''\n", " 读取本地验证码图片进行随机加点噪声为新图片\n", " 参数:path:图片路径\n", " 返回:重组后图片 \n", " '''\n", " if re.search('FileInfo0508', path)!=None:\n", " label = path.split('_')[-1][:-4].lower().replace('1','l')\n", "# print(re.search('FileInfo0508', path))\n", " else:\n", " label = path.split('_')[-1][:-4].upper()\n", "# print('label',label)\n", " crop_n = len(label) \n", " img = Image.open(path)\n", " img = img.convert('RGB')\n", " width, height = img.size\n", "# img2 = img2.resize((100,50), Image.BILINEAR)\n", " draw = ImageDraw.Draw(img)\n", " for _ in range(random.randint(0,450)):\n", " draw.point(xy=(random_xy(width,height)),fill=random_color(25, 255)) \n", "# for _ in range(random.randint(0, 3)):\n", "# draw.line(xy=(random_xy(width, height),random_xy(width, height)), fill=random_color(20, 250), width=random.randint(1,2))\n", " return img.resize((200,70), Image.NEAREST), label\n", "\n", "import re\n", "real_imgs = []\n", "paths = 'FileInfo0508_2/*.jpg'\n", "# paths = '/data/esa_sdk/gan/english/*.jpg'\n", "for path in glob.glob(paths)[:2024]:\n", " label = path.split('_')[-1][:-4].lower().replace('1','l')\n", " if len(label) ==5 and re.search('[0-9]', label)==None:\n", " real_imgs.append(path)\n", "random.shuffle(real_imgs)\n", "img, l = rebuild_img(glob.glob('/data/esa_sdk/gan/english/*.jpg')[0])\n", "l\n", "# plt.imshow(img)\n", "# l2 = [rebuild_img(real_imgs[i])[1] for i in range(200,300)]\n", "# [characters.find(x) for x in l2[6]]" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2024" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import re\n", "# real_imgs = []\n", "paths = 'FileInfo0508/*.jpg'\n", "# paths = '/data/esa_sdk/gan/english/*.jpg'\n", "# for path in glob.glob(paths)[:1024]:\n", "# label = path.split('_')[-1][:-4].lower()\n", "# if re.search('FileInfo0508', paths)!=None:\n", "# print(paths)\n", "# if len(label) ==4 and re.search('[0-9]', label)==None:\n", "# real_imgs.append(path)\n", "# img, l = rebuild_img(real_imgs[0])\n", "# plt.imshow(img)\n", "len(real_imgs)" ] }, { "cell_type": "code", "execution_count": 9, "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=200, height=70, \n", " input_length=13, label_length=6, chars_len=(5, 5)): # 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.chars_len = chars_len\n", "# self.label_length = self.n_len\n", " self.n_class = len(characters)\n", " self.generator = ImageCaptcha(width=width, height=height, font_sizes=(12,20,18,25))\n", "# self.fonts_list = glob.glob('/usr/share/fonts/WindowsFonts/fonts/*.ttf')\n", " self.fonts_list = ['/usr/share/fonts/WindowsFonts/fonts/arial.ttf','/usr/share/fonts/WindowsFonts/fonts/ANTQUAB.TTF',\n", " '/usr/share/fonts/WindowsFonts/fonts/BKANT.TTF','/usr/share/fonts/WindowsFonts/fonts/cambriab.ttf',\n", " '/usr/share/fonts/WindowsFonts/fonts/comic.ttf','/usr/share/fonts/WindowsFonts/fonts/GOTHIC.TTF']\n", " \n", " def __len__(self):\n", " return self.steps\n", "\n", " def __getitem__(self, idx):\n", " batch_label_length = random.choice([5])\n", "# print('batch_label_length',batch_label_length)\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", "# y = np.zeros((self.batch_size, batch_label_length), dtype=np.uint8)\n", " input_length = np.ones(self.batch_size)*self.input_length\n", " label_length = np.ones(self.batch_size)*batch_label_length \n", "# print('id(x):',id(x))\n", "# print('id(batch_label_length)', id(batch_label_length))\n", " if batch_label_length == 4: \n", "# print('batch_label_length == 4', batch_label_length == 4)\n", " for i in range(self.batch_size):\n", "# print('len 4',y.shape, i)\n", " # 定义验证码字符集 (大写字母、小写字母、大写字母+数字)\n", " gen_characters = random.choice([string.ascii_lowercase, string.ascii_uppercase, string.digits + string.ascii_uppercase]) \n", " if i % 4 == 0: \n", " random_str = ''.join([random.choice(gen_characters) for j in range(batch_label_length)])\n", " image = generate_image(random_str, background =random_color(255,255), width=200, height=70)\n", " elif i % 4 ==1:\n", " random_str = ''.join([random.choice(gen_characters) for j in range(batch_label_length)])\n", " image = gen_captcha(random_str, fonts=self.fonts_list, fill=(0,250), rotate=(-10,10), line=(0,2), point=(0,500), \n", " color=(0,255), bg=tuple([random.randint(240,255) for _ in range(3)]))\n", " elif i % 6 < 5:\n", " random_str = ''.join([random.choice(gen_characters) for j in range(batch_label_length)])\n", " image = gen_captcha(random_str, fonts=self.fonts_list, fill=(0,250), rotate=(-20,20), line=(0,10), point=(0,500), \n", " color=(0,255), bg=tuple([random.randint(230,255) for _ in range(3)])) \n", " else:\n", " image, random_str = rebuild_img(random.choice(glob.glob('/data/esa_sdk/gan/english/*.jpg'))) \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", " elif batch_label_length == 5: \n", "# print('batch_label_length == 5',batch_label_length == 5)\n", " for i in range(self.batch_size):\n", "# print('len 5',y.shape)\n", " # 定义验证码字符集 (大写字母、小写字母、大写字母+数字)\n", " gen_characters = random.choice([string.ascii_lowercase, string.ascii_uppercase, string.digits + string.ascii_uppercase])\n", " if i % 4 == 0: \n", " random_str = ''.join([random.choice(gen_characters) for j in range(batch_label_length)])\n", " image = generate_image(random_str, background =random_color(255,255), width=200, height=70) \n", " elif i % 4 ==1:\n", " random_str = ''.join([random.choice(gen_characters) for j in range(batch_label_length)])\n", " image = gen_captcha(random_str, fonts=self.fonts_list, fill=(0,250), rotate=(-10,10), line=(0,2), point=(100,500), \n", " color=(0,255), bg=tuple([random.randint(240,255) for _ in range(3)]))\n", " elif i % 6 < 5:\n", " random_str = ''.join([random.choice(gen_characters) for j in range(batch_label_length)])\n", " image = gen_captcha(random_str, fonts=self.fonts_list, fill=(0,250), rotate=(-20,20), line=(0,10), point=(0,500), \n", " color=(0,255), bg=tuple([random.randint(240,255) for _ in range(3)])) \n", " else:\n", " image, random_str = rebuild_img(random.choice(real_imgs)) \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", " else:\n", "# print('batch_label_length == 6',batch_label_length == 6)\n", " for i in range(self.batch_size):\n", "# print('len 6',y.shape)\n", " # 定义验证码字符集 (大写字母、小写字母、大写字母+数字)\n", " gen_characters = random.choice([string.ascii_lowercase, string.ascii_uppercase, string.digits + string.ascii_uppercase])\n", "# if i % 4 <= 2: \n", " random_str = ''.join([random.choice(gen_characters) for j in range(batch_label_length)])\n", " image = generate_image(random_str, background =random_color(240,255), width=200, height=70) \n", "# else:\n", "# image, random_str = rebuild_img(random.choice(real_imgs)) \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", " return [X, y, input_length, label_length], np.ones(self.batch_size)\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[14 24 23 31 35 62]\n", "139974952355280\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "image/png": { "height": 163, "width": 370 }, "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# # 测试生成器\n", "data = CaptchaSequence(characters, batch_size=4,n_len=6, width=200, height=70, steps=1, chars_len=(4, 6))\n", "[X_test, y_test, input_length, label_length], _ = data[0]\n", "idx =0\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)\n", "print(y_test[idx])\n", "# characters\n", "print(id(X_test))" ] }, { "cell_type": "code", "execution_count": 470, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1, 30, 80, 3)\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 470, "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": 45, "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": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.27000000000000002" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# model.load_weights('digit4to6_ctc_best2.h5')\n", "evaluate(base_model,batch_size=1, steps=10)" ] }, { "cell_type": "code", "execution_count": 12, "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", "# print(f'\\nacc: {acc*100:.4f}')" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "input_1 True\n", "conv2d True\n", "batch_normalization True\n", "activation True\n", "conv2d_1 True\n", "batch_normalization_1 True\n", "activation_1 True\n", "max_pooling2d True\n" ] } ], "source": [ "model.load_weights('gru_english4to6_ctc_best.h5')\n", "# 前8层不训练\n", "for layer in model.layers[:8]:\n", " layer.trainable = True\n", " print(layer.name, layer.trainable)\n", "# del train_data\n", "# del valid_data" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/200\n", "1000/1000 [==============================] - 349s 349ms/step - loss: 0.0947 - val_loss: 0.1069\n", "Epoch 2/200\n", "1000/1000 [==============================] - 348s 348ms/step - loss: 0.0913 - val_loss: 1.0192\n", "Epoch 3/200\n", "1000/1000 [==============================] - 347s 347ms/step - loss: 0.0897 - val_loss: 0.1711\n", "Epoch 4/200\n", "1000/1000 [==============================] - 383s 383ms/step - loss: 0.0828 - val_loss: 0.9216\n", "Epoch 5/200\n", "1000/1000 [==============================] - 358s 358ms/step - loss: 0.0821 - val_loss: 0.0882\n", "Epoch 6/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0796 - val_loss: 0.1026\n", "Epoch 7/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0763 - val_loss: 0.3352\n", "Epoch 8/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0737 - val_loss: 0.0766\n", "Epoch 9/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0689 - val_loss: 0.1046\n", "Epoch 10/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0692 - val_loss: 0.7021\n", "Epoch 11/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0673 - val_loss: 0.1087\n", "Epoch 12/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0681 - val_loss: 0.0853\n", "Epoch 13/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0649 - val_loss: 0.1258\n", "Epoch 14/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0627 - val_loss: 0.0668\n", "Epoch 15/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0637 - val_loss: 1.6448\n", "Epoch 16/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0611 - val_loss: 0.0827\n", "Epoch 17/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0625 - val_loss: 0.1113\n", "Epoch 18/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0564 - val_loss: 0.0621\n", "Epoch 19/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0582 - val_loss: 0.0628\n", "Epoch 20/200\n", "1000/1000 [==============================] - 346s 346ms/step - loss: 0.0584 - val_loss: 0.1358\n", "Epoch 21/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0571 - val_loss: 0.0546\n", "Epoch 22/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0556 - val_loss: 0.0610\n", "Epoch 23/200\n", "1000/1000 [==============================] - 346s 346ms/step - loss: 0.0539 - val_loss: 0.2364\n", "Epoch 24/200\n", "1000/1000 [==============================] - 361s 361ms/step - loss: 0.0529 - val_loss: 0.0595\n", "Epoch 25/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0513 - val_loss: 0.2403\n", "Epoch 26/200\n", "1000/1000 [==============================] - 347s 347ms/step - loss: 0.0495 - val_loss: 0.0732\n", "Epoch 27/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0502 - val_loss: 0.0597\n", "Epoch 28/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0477 - val_loss: 0.0854\n", "Epoch 29/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0489 - val_loss: 0.0709\n", "Epoch 30/200\n", "1000/1000 [==============================] - 346s 346ms/step - loss: 0.0470 - val_loss: 0.5855\n", "Epoch 31/200\n", "1000/1000 [==============================] - 361s 361ms/step - loss: 0.0461 - val_loss: 0.1502\n", "Epoch 32/200\n", "1000/1000 [==============================] - 353s 353ms/step - loss: 0.0473 - val_loss: 0.1252\n", "Epoch 33/200\n", "1000/1000 [==============================] - 356s 356ms/step - loss: 0.0472 - val_loss: 0.1643\n", "Epoch 34/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0448 - val_loss: 0.2586\n", "Epoch 35/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0465 - val_loss: 0.5817\n", "Epoch 36/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0428 - val_loss: 0.0519\n", "Epoch 37/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0466 - val_loss: 0.0444\n", "Epoch 38/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0431 - val_loss: 0.5121\n", "Epoch 39/200\n", "1000/1000 [==============================] - 348s 348ms/step - loss: 0.0451 - val_loss: 0.0593\n", "Epoch 40/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0436 - val_loss: 0.1909\n", "Epoch 41/200\n", "1000/1000 [==============================] - 345s 345ms/step - loss: 0.0412 - val_loss: 0.6993\n", "Epoch 42/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0398 - val_loss: 0.1674\n", "Epoch 43/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0398 - val_loss: 1.5403\n", "Epoch 44/200\n", "1000/1000 [==============================] - 353s 353ms/step - loss: 0.0377 - val_loss: 0.0451\n", "Epoch 45/200\n", "1000/1000 [==============================] - 359s 359ms/step - loss: 0.0384 - val_loss: 0.3528\n", "Epoch 46/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0380 - val_loss: 0.0444\n", "Epoch 47/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0396 - val_loss: 0.0402\n", "Epoch 48/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0404 - val_loss: 0.1070\n", "Epoch 49/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0396 - val_loss: 0.1598\n", "Epoch 50/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0370 - val_loss: 0.0805\n", "Epoch 51/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0389 - val_loss: 1.7038\n", "Epoch 52/200\n", "1000/1000 [==============================] - 346s 346ms/step - loss: 0.0348 - val_loss: 0.7530\n", "Epoch 53/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0366 - val_loss: 0.0703\n", "Epoch 54/200\n", "1000/1000 [==============================] - 348s 348ms/step - loss: 0.0361 - val_loss: 0.2907\n", "Epoch 55/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0375 - val_loss: 0.0661\n", "Epoch 56/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0380 - val_loss: 3.1149\n", "Epoch 57/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0340 - val_loss: 0.1123\n", "Epoch 58/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0343 - val_loss: 0.0794\n", "Epoch 59/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0349 - val_loss: 6.1426\n", "Epoch 60/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0350 - val_loss: 0.1803\n", "Epoch 61/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0339 - val_loss: 0.0547\n", "Epoch 62/200\n", "1000/1000 [==============================] - 347s 347ms/step - loss: 0.0342 - val_loss: 0.4151\n", "Epoch 63/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0341 - val_loss: 0.1174\n", "Epoch 64/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0324 - val_loss: 0.0623\n", "Epoch 65/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0322 - val_loss: 0.3983\n", "Epoch 66/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0321 - val_loss: 0.0439\n", "Epoch 67/200\n", "1000/1000 [==============================] - 381s 381ms/step - loss: 0.0340 - val_loss: 0.4052\n", "Epoch 68/200\n", "1000/1000 [==============================] - 350s 350ms/step - loss: 0.0312 - val_loss: 1.0505\n", "Epoch 69/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0311 - val_loss: 0.0453\n", "Epoch 70/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0326 - val_loss: 0.0362\n", "Epoch 71/200\n", "1000/1000 [==============================] - 347s 347ms/step - loss: 0.0319 - val_loss: 0.0431\n", "Epoch 72/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0307 - val_loss: 0.0488\n", "Epoch 73/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0289 - val_loss: 0.0524\n", "Epoch 74/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0327 - val_loss: 0.0397\n", "Epoch 75/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0301 - val_loss: 1.9282\n", "Epoch 76/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0298 - val_loss: 1.1432\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 77/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0300 - val_loss: 0.0760\n", "Epoch 78/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0308 - val_loss: 0.0290\n", "Epoch 79/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0302 - val_loss: 1.0770\n", "Epoch 80/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0278 - val_loss: 0.0412\n", "Epoch 81/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0330 - val_loss: 0.0311\n", "Epoch 82/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0297 - val_loss: 1.2792\n", "Epoch 83/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0296 - val_loss: 0.2815\n", "Epoch 84/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0282 - val_loss: 0.1074\n", "Epoch 85/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0294 - val_loss: 0.1222\n", "Epoch 86/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0275 - val_loss: 0.0943\n", "Epoch 87/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0280 - val_loss: 0.5908\n", "Epoch 88/200\n", "1000/1000 [==============================] - 374s 374ms/step - loss: 0.0271 - val_loss: 0.0384\n", "Epoch 89/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0281 - val_loss: 0.0594\n", "Epoch 90/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0267 - val_loss: 0.3062\n", "Epoch 91/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0278 - val_loss: 0.0256\n", "Epoch 92/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0273 - val_loss: 0.0623\n", "Epoch 93/200\n", "1000/1000 [==============================] - 345s 345ms/step - loss: 0.0250 - val_loss: 0.0422\n", "Epoch 94/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0258 - val_loss: 0.0676\n", "Epoch 95/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0264 - val_loss: 0.0303\n", "Epoch 96/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0260 - val_loss: 0.0289\n", "Epoch 97/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0266 - val_loss: 0.0874\n", "Epoch 98/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0268 - val_loss: 0.0782\n", "Epoch 99/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0243 - val_loss: 0.1453\n", "Epoch 100/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0256 - val_loss: 0.0350\n", "Epoch 101/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0255 - val_loss: 1.9497\n", "Epoch 102/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0260 - val_loss: 0.9368\n", "Epoch 103/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0249 - val_loss: 0.0303\n", "Epoch 104/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0266 - val_loss: 0.0741\n", "Epoch 105/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0248 - val_loss: 0.1845\n", "Epoch 106/200\n", "1000/1000 [==============================] - 358s 358ms/step - loss: 0.0245 - val_loss: 2.2114\n", "Epoch 107/200\n", "1000/1000 [==============================] - 359s 359ms/step - loss: 0.0253 - val_loss: 0.1818\n", "Epoch 108/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0240 - val_loss: 0.0289\n", "Epoch 109/200\n", "1000/1000 [==============================] - 345s 345ms/step - loss: 0.0237 - val_loss: 0.5190\n", "Epoch 110/200\n", "1000/1000 [==============================] - 353s 353ms/step - loss: 0.0216 - val_loss: 0.1273\n", "Epoch 111/200\n", "1000/1000 [==============================] - 359s 359ms/step - loss: 0.0244 - val_loss: 0.0289\n", "Epoch 112/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0248 - val_loss: 0.0847\n", "Epoch 113/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0238 - val_loss: 0.0349\n", "Epoch 114/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0242 - val_loss: 2.8033\n", "Epoch 115/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0238 - val_loss: 5.4596\n", "Epoch 116/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0238 - val_loss: 0.1535\n", "Epoch 117/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0225 - val_loss: 0.0663\n", "Epoch 118/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0225 - val_loss: 0.0448\n", "Epoch 119/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0240 - val_loss: 2.5194\n", "Epoch 120/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0242 - val_loss: 0.1277\n", "Epoch 121/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0227 - val_loss: 0.1144\n", "Epoch 122/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0236 - val_loss: 2.1682\n", "Epoch 123/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0234 - val_loss: 0.2609\n", "Epoch 124/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0218 - val_loss: 3.2897\n", "Epoch 125/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0220 - val_loss: 0.2720\n", "Epoch 126/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0234 - val_loss: 0.0580\n", "Epoch 127/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0229 - val_loss: 0.0414\n", "Epoch 128/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0226 - val_loss: 0.0227\n", "Epoch 129/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0217 - val_loss: 0.2672\n", "Epoch 130/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0239 - val_loss: 0.0544\n", "Epoch 131/200\n", "1000/1000 [==============================] - 356s 356ms/step - loss: 0.0226 - val_loss: 0.0195\n", "Epoch 132/200\n", "1000/1000 [==============================] - 349s 349ms/step - loss: 0.0221 - val_loss: 0.0278\n", "Epoch 133/200\n", "1000/1000 [==============================] - 348s 348ms/step - loss: 0.0216 - val_loss: 0.2993\n", "Epoch 134/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0216 - val_loss: 0.0453\n", "Epoch 135/200\n", "1000/1000 [==============================] - 346s 346ms/step - loss: 0.0202 - val_loss: 0.0403\n", "Epoch 136/200\n", "1000/1000 [==============================] - 346s 346ms/step - loss: 0.0221 - val_loss: 0.0317\n", "Epoch 137/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0217 - val_loss: 0.0287\n", "Epoch 138/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0221 - val_loss: 0.1488\n", "Epoch 139/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0223 - val_loss: 0.9375\n", "Epoch 140/200\n", "1000/1000 [==============================] - 347s 347ms/step - loss: 0.0211 - val_loss: 0.3113\n", "Epoch 141/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0217 - val_loss: 0.0258\n", "Epoch 142/200\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0212 - val_loss: 1.5649\n", "Epoch 143/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0203 - val_loss: 0.0534\n", "Epoch 144/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0210 - val_loss: 0.0252\n", "Epoch 145/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0202 - val_loss: 0.3474\n", "Epoch 146/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0205 - val_loss: 1.5241\n", "Epoch 147/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0211 - val_loss: 0.0248\n", "Epoch 148/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0194 - val_loss: 0.0378\n", "Epoch 149/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0190 - val_loss: 0.7174\n", "Epoch 150/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0197 - val_loss: 0.0361\n", "Epoch 151/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0213 - val_loss: 0.2472\n", "Epoch 152/200\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0196 - val_loss: 0.7572\n", "Epoch 153/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0201 - val_loss: 2.8542\n", "Epoch 154/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0189 - val_loss: 0.1633\n", "Epoch 155/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0199 - val_loss: 0.7304\n", "Epoch 156/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0196 - val_loss: 0.0891\n", "Epoch 157/200\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0185 - val_loss: 0.1303\n", "Epoch 158/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0200 - val_loss: 0.1431\n", "Epoch 159/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0193 - val_loss: 0.0320\n", "Epoch 160/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0195 - val_loss: 0.0268\n", "Epoch 161/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0180 - val_loss: 0.0667\n", "Epoch 162/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0184 - val_loss: 0.0699\n", "Epoch 163/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0192 - val_loss: 0.0278\n", "Epoch 164/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0195 - val_loss: 2.8104\n", "Epoch 165/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0197 - val_loss: 0.0558\n", "Epoch 166/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0190 - val_loss: 0.0255\n", "Epoch 167/200\n", "1000/1000 [==============================] - 344s 344ms/step - loss: 0.0201 - val_loss: 0.9792\n", "Epoch 168/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0190 - val_loss: 0.0349\n", "Epoch 169/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0197 - val_loss: 0.0832\n", "Epoch 170/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0191 - val_loss: 0.0273\n", "Epoch 171/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0186 - val_loss: 0.0233\n", "Epoch 172/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0200 - val_loss: 0.2878\n", "Epoch 173/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0207 - val_loss: 0.4199\n", "Epoch 174/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0191 - val_loss: 0.0778\n", "Epoch 175/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0192 - val_loss: 0.0261\n", "Epoch 176/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0186 - val_loss: 0.0293\n", "Epoch 177/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0195 - val_loss: 0.0347\n", "Epoch 178/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0176 - val_loss: 0.2089\n", "Epoch 179/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0178 - val_loss: 0.1249\n", "Epoch 180/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0172 - val_loss: 0.1915\n", "Epoch 181/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0177 - val_loss: 0.0207\n", "Epoch 182/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0202 - val_loss: 6.6726\n", "Epoch 183/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0171 - val_loss: 0.1873\n", "Epoch 184/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0175 - val_loss: 0.0202\n", "Epoch 185/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0166 - val_loss: 0.2659\n", "Epoch 186/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0158 - val_loss: 0.0221\n", "Epoch 187/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0172 - val_loss: 1.3676\n", "Epoch 188/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0186 - val_loss: 0.1579\n", "Epoch 189/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0182 - val_loss: 2.7702\n", "Epoch 190/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0160 - val_loss: 0.0439\n", "Epoch 191/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0178 - val_loss: 0.0375\n", "Epoch 192/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0167 - val_loss: 0.0273\n", "Epoch 193/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0174 - val_loss: 0.0351\n", "Epoch 194/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0182 - val_loss: 0.0310\n", "Epoch 195/200\n", "1000/1000 [==============================] - 345s 345ms/step - loss: 0.0183 - val_loss: 0.0383\n", "Epoch 196/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0170 - val_loss: 0.0727\n", "Epoch 197/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0180 - val_loss: 0.0562\n", "Epoch 198/200\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0170 - val_loss: 0.0275\n", "Epoch 199/200\n", "1000/1000 [==============================] - 340s 340ms/step - loss: 0.0170 - val_loss: 0.7341\n", "Epoch 200/200\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0184 - val_loss: 0.0294\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Evaluate()\n", "# 模型训练\n", "from tensorflow.keras.callbacks import EarlyStopping, CSVLogger, ModelCheckpoint\n", "from tensorflow.keras.optimizers import *\n", "\n", "# model.load_weights('gru_english4to6_ctc_best.h5')\n", "\n", "# train_data = CaptchaSequence(characters, batch_size=128, steps=1000,input_length=13, label_length=6,chars_len=(5, 5)) # (characters, batch_size=128, steps=1000)\n", "# valid_data = CaptchaSequence(characters, batch_size=128, steps=100,input_length=13, label_length=6,chars_len=(5, 5)) # (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=3),ModelCheckpoint('gru_english4to6_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=8, validation_data=valid_data, workers=2, use_multiprocessing=True,\n", "# callbacks=callbacks)\n", "\n", "train_data = CaptchaSequence(characters, batch_size=128, steps=1000,input_length=13, label_length=6) # (characters, batch_size=128, steps=1000)\n", "valid_data = CaptchaSequence(characters, batch_size=128, steps=100,input_length=13, label_length=6) # (characters, batch_size=128, steps=100)\n", "# 载入最好的模型继续训练一会\n", "model.load_weights('gru_english4to6_ctc_best.h5')\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_english4to6_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=200, validation_data=valid_data, workers=4, use_multiprocessing=True,\n", " callbacks=callbacks)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/300\n", "1000/1000 [==============================] - 293s 293ms/step - loss: 0.0032 - val_loss: 0.0028\n", "Epoch 2/300\n", "1000/1000 [==============================] - 310s 310ms/step - loss: 0.0024 - val_loss: 0.0102\n", "Epoch 3/300\n", "1000/1000 [==============================] - 311s 311ms/step - loss: 0.0029 - val_loss: 0.0028\n", "Epoch 4/300\n", "1000/1000 [==============================] - 292s 292ms/step - loss: 0.0018 - val_loss: 17.9769\n", "Epoch 5/300\n", "1000/1000 [==============================] - 324s 324ms/step - loss: 0.0022 - val_loss: 0.0018\n", "Epoch 6/300\n", "1000/1000 [==============================] - 310s 310ms/step - loss: 0.0025 - val_loss: 0.0032\n", "Epoch 7/300\n", "1000/1000 [==============================] - 315s 315ms/step - loss: 0.0022 - val_loss: 0.0027\n", "Epoch 8/300\n", "1000/1000 [==============================] - 309s 309ms/step - loss: 0.0016 - val_loss: 0.0023\n", "Epoch 9/300\n", "1000/1000 [==============================] - 328s 328ms/step - loss: 0.0018 - val_loss: 0.0018\n", "Epoch 10/300\n", "1000/1000 [==============================] - 309s 309ms/step - loss: 0.0019 - val_loss: 0.2085\n", "Epoch 11/300\n", "1000/1000 [==============================] - 296s 296ms/step - loss: 0.0017 - val_loss: 15.9265\n", "Epoch 12/300\n", "1000/1000 [==============================] - 306s 306ms/step - loss: 0.0013 - val_loss: 0.1947\n", "Epoch 13/300\n", "1000/1000 [==============================] - 357s 357ms/step - loss: 0.0020 - val_loss: 0.0032\n", "Epoch 14/300\n", "1000/1000 [==============================] - 327s 327ms/step - loss: 0.0017 - val_loss: 9.3167e-04\n", "Epoch 15/300\n", "1000/1000 [==============================] - 322s 322ms/step - loss: 0.0013 - val_loss: 0.0012\n", "Epoch 16/300\n", "1000/1000 [==============================] - 318s 318ms/step - loss: 0.0019 - val_loss: 0.0032\n", "Epoch 17/300\n", "1000/1000 [==============================] - 364s 364ms/step - loss: 0.0012 - val_loss: 0.0014\n", "Epoch 18/300\n", "1000/1000 [==============================] - 345s 345ms/step - loss: 0.0014 - val_loss: 0.1355\n", "Epoch 19/300\n", "1000/1000 [==============================] - 354s 354ms/step - loss: 0.0014 - val_loss: 5.9481e-04\n", "Epoch 20/300\n", "1000/1000 [==============================] - 386s 386ms/step - loss: 0.0014 - val_loss: 0.0018\n", "Epoch 21/300\n", "1000/1000 [==============================] - 366s 366ms/step - loss: 0.0013 - val_loss: 0.0014\n", "Epoch 22/300\n", "1000/1000 [==============================] - 359s 359ms/step - loss: 0.0012 - val_loss: 0.0015\n", "Epoch 23/300\n", "1000/1000 [==============================] - 381s 381ms/step - loss: 0.0012 - val_loss: 4.8570e-04\n", "Epoch 24/300\n", "1000/1000 [==============================] - 342s 342ms/step - loss: 0.0019 - val_loss: 6.8652e-04\n", "Epoch 25/300\n", "1000/1000 [==============================] - 345s 345ms/step - loss: 0.0014 - val_loss: 8.7500e-04\n", "Epoch 26/300\n", "1000/1000 [==============================] - 346s 346ms/step - loss: 0.0018 - val_loss: 3.8954e-04\n", "Epoch 27/300\n", "1000/1000 [==============================] - 370s 370ms/step - loss: 0.0010 - val_loss: 0.0012\n", "Epoch 28/300\n", "1000/1000 [==============================] - 363s 363ms/step - loss: 0.0012 - val_loss: 0.0017\n", "Epoch 29/300\n", "1000/1000 [==============================] - 382s 382ms/step - loss: 0.0013 - val_loss: 0.0015\n", "Epoch 30/300\n", "1000/1000 [==============================] - 338s 338ms/step - loss: 0.0015 - val_loss: 9.9728e-04\n", "Epoch 31/300\n", "1000/1000 [==============================] - 345s 345ms/step - loss: 0.0012 - val_loss: 0.0143\n", "Epoch 32/300\n", "1000/1000 [==============================] - 327s 327ms/step - loss: 0.0012 - val_loss: 0.0013\n", "Epoch 33/300\n", "1000/1000 [==============================] - 361s 361ms/step - loss: 9.3152e-04 - val_loss: 0.0014\n", "Epoch 34/300\n", "1000/1000 [==============================] - 343s 343ms/step - loss: 0.0017 - val_loss: 0.0012\n", "Epoch 35/300\n", "1000/1000 [==============================] - 341s 341ms/step - loss: 0.0018 - val_loss: 4.7312e-04\n", "Epoch 36/300\n", "1000/1000 [==============================] - 339s 339ms/step - loss: 0.0010 - val_loss: 6.0925e-04\n", "Epoch 37/300\n", "1000/1000 [==============================] - 349s 349ms/step - loss: 0.0013 - val_loss: 5.1787e-04\n", "Epoch 38/300\n", "1000/1000 [==============================] - 345s 345ms/step - loss: 8.9243e-04 - val_loss: 7.5217e-04\n", "Epoch 39/300\n", "1000/1000 [==============================] - 337s 337ms/step - loss: 0.0012 - val_loss: 0.0012\n", "Epoch 40/300\n", "1000/1000 [==============================] - 346s 346ms/step - loss: 0.0013 - val_loss: 7.8339e-04\n", "Epoch 41/300\n", "1000/1000 [==============================] - 367s 367ms/step - loss: 9.1171e-04 - val_loss: 7.2432e-04\n", "Epoch 42/300\n", "1000/1000 [==============================] - 365s 365ms/step - loss: 0.0017 - val_loss: 4.9699e-04\n", "Epoch 43/300\n", "1000/1000 [==============================] - 385s 385ms/step - loss: 0.0012 - val_loss: 0.0013\n", "Epoch 44/300\n", "1000/1000 [==============================] - 362s 362ms/step - loss: 0.0016 - val_loss: 3.5807e-04\n", "Epoch 45/300\n", "1000/1000 [==============================] - 361s 361ms/step - loss: 9.0703e-04 - val_loss: 5.6368e-04\n", "Epoch 46/300\n", "1000/1000 [==============================] - 356s 356ms/step - loss: 0.0010 - val_loss: 0.0011\n", "Epoch 47/300\n", "1000/1000 [==============================] - 391s 391ms/step - loss: 8.9139e-04 - val_loss: 6.0659e-04\n", "Epoch 48/300\n", " 104/1000 [==>...........................] - ETA: 4:29 - loss: 3.8686e-04" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Process ForkPoolWorker-883:\n", "Process ForkPoolWorker-881:\n", "Process ForkPoolWorker-882:\n", "Process ForkPoolWorker-880:\n", "Traceback (most recent call last):\n", "Traceback (most recent call last):\n", "Traceback (most recent call last):\n", "Traceback (most recent call last):\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/process.py\", line 254, in _bootstrap\n", " self.run()\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/process.py\", line 254, in _bootstrap\n", " self.run()\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/process.py\", line 254, in _bootstrap\n", " self.run()\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/process.py\", line 93, in run\n", " self._target(*self._args, **self._kwargs)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/process.py\", line 254, in _bootstrap\n", " self.run()\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/pool.py\", line 119, in worker\n", " result = (True, func(*args, **kwds))\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/process.py\", line 93, in run\n", " self._target(*self._args, **self._kwargs)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/process.py\", line 93, in run\n", " self._target(*self._args, **self._kwargs)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/pool.py\", line 108, in worker\n", " task = get()\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/process.py\", line 93, in run\n", " self._target(*self._args, **self._kwargs)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/utils/data_utils.py\", line 432, in get_index\n", " return _SHARED_SEQUENCES[uid][i]\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/pool.py\", line 119, in worker\n", " result = (True, func(*args, **kwds))\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/queues.py\", line 343, in get\n", " res = self._reader.recv_bytes()\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/utils/data_utils.py\", line 432, in get_index\n", " return _SHARED_SEQUENCES[uid][i]\n", " File \"\", line 42, in __getitem__\n", " image = generate_image(random_str, background =random_color(255,255), width=200, height=70)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/connection.py\", line 216, in recv_bytes\n", " buf = self._recv_bytes(maxlength)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/pool.py\", line 108, in worker\n", " task = get()\n", " File \"\", line 146, in generate_image\n", " draw.point(xy=(random_xy(width,height)),fill=random_color(155, 255))\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/connection.py\", line 407, in _recv_bytes\n", " buf = self._recv(4)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/queues.py\", line 342, in get\n", " with self._rlock:\n", " File \"\", line 42, in __getitem__\n", " image = generate_image(random_str, background =random_color(255,255), width=200, height=70)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/PIL/ImageDraw.py\", line 231, in point\n", " ink, fill = self._getink(fill)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/synchronize.py\", line 96, in __enter__\n", " return self._semlock.__enter__()\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/multiprocessing/connection.py\", line 379, in _recv\n", " chunk = read(handle, remaining)\n", "KeyboardInterrupt\n", "KeyboardInterrupt\n", " File \"\", line 115, in generate_image\n", " char_img = get_char_img(char=c, font=font, color=ch_color, angle=random.randint(-10,10))\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/PIL/ImageDraw.py\", line 101, in _getink\n", " def _getink(self, ink, fill=None):\n", "KeyboardInterrupt\n", " File \"\", line 95, in get_char_img\n", " rot = im.rotate(angle,Image.BILINEAR,expand=1)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/PIL/Image.py\", line 1915, in rotate\n", " fillcolor=fillcolor)\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/PIL/Image.py\", line 2192, in transform\n", " return self.convert('RGBa').transform(\n", " File \"/home/python/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/PIL/Image.py\", line 1030, in convert\n", " im = self.im.convert(mode, dither)\n", "KeyboardInterrupt\n" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mloss\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m'ctc'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mlambda\u001b[0m \u001b[0my_true\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_pred\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0my_pred\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mAdam\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1e-4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mamsgrad\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m model.fit_generator(train_data, epochs=300, validation_data=valid_data, workers=4, use_multiprocessing=True,\n\u001b[0;32m---> 13\u001b[0;31m callbacks=callbacks)\n\u001b[0m", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/engine/training.py\u001b[0m in \u001b[0;36mfit_generator\u001b[0;34m(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)\u001b[0m\n\u001b[1;32m 1777\u001b[0m \u001b[0muse_multiprocessing\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0muse_multiprocessing\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1778\u001b[0m \u001b[0mshuffle\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mshuffle\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1779\u001b[0;31m initial_epoch=initial_epoch)\n\u001b[0m\u001b[1;32m 1780\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1781\u001b[0m def evaluate_generator(self,\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/engine/training_generator.py\u001b[0m in \u001b[0;36mfit_generator\u001b[0;34m(model, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)\u001b[0m\n\u001b[1;32m 202\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 203\u001b[0m outs = model.train_on_batch(\n\u001b[0;32m--> 204\u001b[0;31m x, y, sample_weight=sample_weight, class_weight=class_weight)\n\u001b[0m\u001b[1;32m 205\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 206\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mouts\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/engine/training.py\u001b[0m in \u001b[0;36mtrain_on_batch\u001b[0;34m(self, x, y, sample_weight, class_weight)\u001b[0m\n\u001b[1;32m 1550\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1551\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_train_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1552\u001b[0;31m \u001b[0moutputs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrain_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mins\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1553\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1554\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/backend.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, inputs)\u001b[0m\n\u001b[1;32m 2912\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_callable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfeed_arrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfeed_symbols\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msymbol_vals\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msession\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2913\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2914\u001b[0;31m \u001b[0mfetched\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_callable_fn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0marray_vals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2915\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_fetch_callbacks\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfetched\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_fetches\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2916\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfetched\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/client/session.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1380\u001b[0m ret = tf_session.TF_SessionRunCallable(\n\u001b[1;32m 1381\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_session\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_session\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_handle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstatus\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1382\u001b[0;31m run_metadata_ptr)\n\u001b[0m\u001b[1;32m 1383\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrun_metadata\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1384\u001b[0m \u001b[0mproto_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtf_session\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTF_GetBuffer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrun_metadata_ptr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "from tensorflow.keras.callbacks import EarlyStopping, CSVLogger, ModelCheckpoint\n", "from tensorflow.keras.optimizers import *\n", "# 载入最好的模型继续训练一会\n", "model.load_weights('gru_english4to6_ctc_best.h5')\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),\n", "# CSVLogger('ctc.csv', append=True), ModelCheckpoint('ctc_best.h5', save_best_only=True)]\n", "callbacks = [CSVLogger('ctc.csv', append=True), ModelCheckpoint('gru_english4to6_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": 22, "metadata": {}, "outputs": [], "source": [ "# model.load_weights('ctc_best.h5')\n", "# model.load_weights('gru_english4to6_ctc_best.h5')\n", "# base_model.save('gru_english_base_model.h5')\n", "base_model.load_weights('gru_english_base_model.h5')" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "scrolled": true }, "outputs": [ { "ename": "ValueError", "evalue": "Shapes (1024, 384) and (1024, 192) are incompatible", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# 测试模型\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload_weights\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'gru_english4to6_ctc_best_2.h5'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 19层网络\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mcharacters2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcharacters\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m' '\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/engine/network.py\u001b[0m in \u001b[0;36mload_weights\u001b[0;34m(self, filepath, by_name)\u001b[0m\n\u001b[1;32m 1446\u001b[0m \u001b[0msaving\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload_weights_from_hdf5_group_by_name\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlayers\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1447\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1448\u001b[0;31m \u001b[0msaving\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mload_weights_from_hdf5_group\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlayers\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1449\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1450\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_post_build_cleanup\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/engine/saving.py\u001b[0m in \u001b[0;36mload_weights_from_hdf5_group\u001b[0;34m(f, layers)\u001b[0m\n\u001b[1;32m 800\u001b[0m str(len(weight_values)) + ' elements.')\n\u001b[1;32m 801\u001b[0m \u001b[0mweight_value_tuples\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msymbolic_weights\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mweight_values\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 802\u001b[0;31m \u001b[0mK\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbatch_set_value\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mweight_value_tuples\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 803\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 804\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/keras/backend.py\u001b[0m in \u001b[0;36mbatch_set_value\u001b[0;34m(tuples)\u001b[0m\n\u001b[1;32m 2712\u001b[0m assign_placeholder = array_ops.placeholder(tf_dtype,\n\u001b[1;32m 2713\u001b[0m shape=value.shape)\n\u001b[0;32m-> 2714\u001b[0;31m \u001b[0massign_op\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0massign\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0massign_placeholder\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2715\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_assign_placeholder\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0massign_placeholder\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2716\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_assign_op\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0massign_op\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/ops/resource_variable_ops.py\u001b[0m in \u001b[0;36massign\u001b[0;34m(self, value, use_locking, name, read_value)\u001b[0m\n\u001b[1;32m 961\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0m_handle_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhandle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 962\u001b[0m \u001b[0mvalue_tensor\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mops\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconvert_to_tensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 963\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_shape\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0massert_is_compatible_with\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue_tensor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 964\u001b[0m assign_op = gen_resource_variable_ops.assign_variable_op(\n\u001b[1;32m 965\u001b[0m self.handle, value_tensor, name=name)\n", "\u001b[0;32m~/anaconda3/envs/dl_nlp/lib/python3.5/site-packages/tensorflow/python/framework/tensor_shape.py\u001b[0m in \u001b[0;36massert_is_compatible_with\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 845\u001b[0m \"\"\"\n\u001b[1;32m 846\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_compatible_with\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 847\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Shapes %s and %s are incompatible\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 848\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 849\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmost_specific_compatible_shape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: Shapes (1024, 384) and (1024, 192) are incompatible" ] } ], "source": [ "# 测试模型\n", "model.load_weights('gru_english4to6_ctc_best_2.h5') # 19层网络 \n", "characters2 = characters + ' '\n", "import time\n", "import re\n", "def get_test_data():\n", " '''\n", " 从本地获取验证码图片并生成测试数据\n", " ''' \n", " X = []\n", " Y = []\n", "# for path in glob.glob('FileInfo0508_2/*.jpg')[:]: #FileInfo0508_2/*.jpg '/data/esa_sdk/gan/english/*.jpg'\n", "# random_str = path.split('_')[-1][:-4].replace('1', 'l') \n", "# if len(random_str) ==5 and re.search('[0-9]', random_str)==None:\n", "# random_str = random_str.lower()\n", "\n", " for path in glob.glob('/data/esa_sdk/gan/english/*.jpg')[:]: \n", " random_str = path.split('_')[-1][:-4]\n", " if len(random_str) ==4: \n", " random_str = random_str.upper()\n", " \n", "# print(random_str)\n", "# if random_str.isdigit() and len(random_str) ==4:\n", " img = Image.open(path)\n", " img = img.convert('RGB')\n", " img = img.resize((200,70), Image.NEAREST)\n", " X.append(np.array(img)/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=5, chars_len=(6,6))\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])[:, :10 ]\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", "# if re.sub(' ','',out) != y_true:\n", " if out != y_true:\n", "# print(' ' in out[-2:])\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('正确数:%d, 错误数:%d'%(pos,neg))\n", "# print('y_test长度:', len(y_test), y_test)\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": 114, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensorflow.python.framework.ops.Tensor" ] }, "execution_count": 114, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ct = K.ctc_decode(y_pred, input_length=np.ones(y_pred.shape[0])*y_pred.shape[1])\n", "type(ct[0][0])" ] }, { "cell_type": "code", "execution_count": 199, "metadata": {}, "outputs": [], "source": [ "evaluate(base_model,batch_size=128, steps=10)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "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()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "20\n" ] } ], "source": [ "import re\n", "num = 0\n", "for path in glob.glob('FileInfo0508/*.jpg'): # Digit5/*.jpg ../FileInfo1031/*.jpg\n", " random_str = path.split('_')[-1][:-4] \n", " if re.search('[a-zA-Z]', random_str) != None and len(random_str) ==4:\n", " num += 1\n", "print(num)" ] } ], "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 }