接着上一篇,这一篇把剩下两个任务做完
- 读取图片和图片预处理;
- 搭建VGG神经网络;
- 开始训练和一些训练技巧;
- 制作新数据集和数据增强;
- 模型融合;
生成验证码:
首先在 查字体网 (百度可以搜到~)查到我们需要的字体
然后下载TTF文件,放到我们的文件目录下。
生成验证码:
调用 数据集.py 程序并输入生成数量,生成验证码
代码:
from PIL import ImageFont, ImageDraw, ImageFilter, Image
import random
import pandas as pd
import numpy as np
import os
import cv2
co = np.array(pd.read_csv('l.csv'))
k = []
num = int(input('请输入生成数目并保存在/pic_data中: '))
for i in co:
k.append(tuple(i))
co = k
# 字体路径
font_path = "RAVIE.TTF"
# 位数
numbers = 1
# 验证码大小
size = (120, 40)
# 背景颜色
bgcolor = (random.randint(0, 255), 0, 0)
# line 干扰线
draw_line = True
# 线数量范围
line_numbers = (1, 4)
def bgfontrange():
global bgcolor
bgcolor = random.choice(co)
source1 = [str(x) for x in range(0, 10)] # 0-9之间
source2 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
source3 = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
"M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
source = []
source.extend(source3)
source.extend(source1)
source.extend(source2)
# 随机生成四个随机数:
def make_text():
return "".join(random.sample(source, numbers)) # "",加上4个随机数
# 随机划线
def make_line(draw, width, height):
begin = (random.randint(0, width), random.randint(0, height))
end = (random.randint(0, width), random.randint(0, height))
draw.line([begin, end], fill=(random.randint(170, 210), random.randint( 130, 170), random.randint(90, 130)), width=random.choice([2, 3])) # 绘线
def create_points(draw, point_chance, width, height):
chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]
for w in range(width):
for h in range(height):
tmp = random.randint(0, 100)
if tmp > 100 - chance:
draw.point((w, h), fill=(random.randint(0, 200), 0, 0))
data = pd.DataFrame()
data1 = []
def rndChar():
return chr(random.randint(65, 122))
def rndColorChar():
return(random.randint(20, 110), random.randint(20, 110), random.randint(20, 110))
# 生成验证码
def make_codepng(index):
width, height = size # 图片的宽度与高度
# RGBA是透明度
image = Image.new("RGB", (width, height), bgcolor) # 创建图片
draw = ImageDraw.Draw(image) # 绘图工具
text = make_text() # 生成随机字符串
font = ImageFont.truetype(font_path, 29) # 定义字体大小
font_width, font_height = font.getsize(text) # 设置字体的宽度与高度
s = ''
for t in range(4):
s1 = make_text()
s = s + s1
bias = random.randint(-5, 5)
draw.text((25*t+10, (height-font_height)/2+bias),
s1, font=font, fill=rndColorChar())
text = s
data1.append(s)
if draw_line:
print("num : {}".format(index), end='\r')
num = random.randint(1, 3)
for i in range(num):
make_line(draw, width, height)
create_points(draw, 6, width, height)
filename = r"./pic_data/"+text+".jpg"
# filename = text + '.jpg'
with open(filename, "wb") as file:
image.save(file, format='JPEG')
if not os.path.exists("./pic_data"):
os.makedirs("./pic_data")
for i in range(num):
bgfontrange() # 背景颜色随机
make_codepng(i)
其中需要的文件是
(l.csv文件保存了对官方给出数据集的背景RGB值的取样)
这样就可以生成一模一样的数据集啦~
模型融合:
一般来说,模型融合可以得到更好的测试集表现结果,当然前提是模型之间相关性越小越好、模型结构差距越大越好。我们这里就使用Voting的方式进行融合,即对同一张图片,使用不同的模型预测进行投票。
这里我做了7个模型,放在了另一个文件夹里:
不同模型采用了不同的预处理方式和网络结构,子文件夹比如Net0,就存放了预处理方式和网络结构及其模型。
由于后来官方改成了提交docker文件,程序改动比较大,这里就不放出来啦,需要源码的留下邮箱哦~
总结:
1、预处理很重要!
2、模型融合很重要!
3、调参数也是一个很重要的环节,这感觉更像一个需要经验的地方,所以有时间不如选一个模型,尝试一下怎么把它的性能调到最高。
下期再见啦~
Ps:下一系列讲一下SSD目标检测算法及其实现,参考了Github上balance大神的SSD-tensorflow,但更多使用了Numpy而非tensorflow实现图片的处理,而且由于balance大神写的时候综合考虑了模型的效率、应用性等等,代码可能比较复杂;这里的话就是使用了一个最简单最直接的方法,参考论文复现的一个SSD-vgg网络,效果如图,尽快更新~
在宿舍随手拍了一张图(然后发现特征很多,干扰也很多,正好适合测试一下目标检测算法),然后第一张是balance大神的300×300的模型的结果,第二张是我们自己从头搭建的模型的结果:
可以看到我们的模型对于小目标检测效果似乎更好一点(比如桌子上的一些bottles),对遮挡目标的检测也比较好(比如这个被衣服挡住的chair);
但是可能存在过拟合的现象,比如把左下角的盆当成了chair(盆:我冤枉啊!),也有把书包检测成chair的情况(书包:我也冤枉啊!)。
先放一下文件目录吧,下期再见~
源码就不分享啦~需要咨询的可加群:850591259