1 综述
有幸参加了2019TinyMind人民币面值及编码识别比赛,比赛的具体背景和要求如下所示。
1.1 比赛背景
1.2 具体任务
比赛一共分类两个任务,第一轮任务是训练AI,识别每张图片的面值,面值一共分为0.1,0.2,0.5,1,2,5,10,50,100,一共9种标签,单位为元。
1.3 数据说明
1.4 第一阶段代码说明
目前本人仅仅参与了第一阶段的面值识别任务,本质上是一个图像分类的任务,现开源代码如下:
1 # _*_ coding:utf-8 _*_
2
3 import os
4 import pandas as pd
5 import numpy as np
6 import random
7 import math
8
9 from PIL import Image
10 from glob import glob
11 from sklearn.model_selection import train_test_split
12 from keras.utils import *
13 from keras.layers import *
14 from keras.models import *
15 from keras.callbacks import *
16 from keras.optimizers import *
17 from keras.applications import *
18
19 import tensorflow as tf
20 gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction = 0.7)
21 config = tf.ConfigProto(gpu_options = gpu_options,allow_soft_placement = True)
22 sess = tf.Session(config = config)
23 #tf.set_session(sess)
24
25 Width = 640
26 Height = 320
27 channel = 3
28 num_classes = 9
29 batch_size = 16
30 epochs = 6
31
32 train_data_path = '../data/train_data/'
33 test_data_path = '../data/public_test_data/'
34 label_list = '../data/train_face_value_label.csv'
35
36 label_pd = pd.read_csv(label_list)
37
38 #看一下训练和测试集中图片的格式,发现全是.jpg格式
39 pic_train_name_list = list(label_pd['name'])
40 pic_train_endName_list = []
41 for sub in pic_train_name_list:
42 s = sub.split('.')[-1]
43 pic_train_endName_list.append(s)
44 print(set(pic_train_endName_list))
45
46 pic_test_name_list = os.listdir(test_data_path)
47 pic_test_endName_list = []
48 for sub in pic_test_name_list:
49 s = sub.split('.')[-1]
50 pic_test_endName_list.append(s)
51 print(set(pic_test_endName_list))
52
53 #面值和类别对应的字典
54 key_value1 = {'0.1':0,'0.2':1,'0.5':2,'1.0':3,'2.0':4,'5.0':5,'10.0':6,'50.0':7,'100.0':8}
55 key_value2 = {0:0.1,1:0.2,2:0.5,3:1,4:2,5:5,6:10,7:50,8:100}
56
57 train_paths = glob(train_data_path + '*.jpg')
58 test_paths = glob(test_data_path + '*.jpg')
59
60 #构建训练集和测试集
61 def get_img(img_paths,Width,Height):
62 X_train = np.zeros((len(img_paths),Height,Width,channel),dtype = np.uint8)
63 y_train = np.zeros((len(img_paths),),dtype = np.uint8)
64 i = 0
65 for img_path in img_paths:
66 img = Image.open(img_path)
67 img = img.convert('RGB')
68 img = img.resize((Width,Height),Image.LANCZOS)
69 arr = np.asarray(img)
70 X_train[i,:,:,:] = arr
71 image_name = img_path.split('/')[-1]
72
73 df = label_pd[label_pd['name'].isin([image_name])]
74 label = str(float(df[df.columns[1]].values))
75 y_train[i] = key_value1[label]
76
77 i = i + 1
78 y_train = np_utils.to_categorical(y_train, num_classes)
79 return X_train, y_train
80
81 #分batch读入,减少内存耗费
82 def get_train_batch(X_path,batch_size,Width,Height):
83 while 1:
84 for i in range(0,len(X_path),batch_size):
85 X_train, y_train = get_img(X_path[i:i + batch_size],Width,Height)
86 yield X_train,y_train
87
88 y_label = []
89 for path in train_paths:
90 image_name = path.split('/')[-1]
91 df = label_pd[label_pd['name'].isin([image_name])]
92 label = str(float(df[df.columns[1]].values))
93 y_label.append(key_value1[label])
94 #将label转化成one-hot
95 y_label = np.array(y_label)
96 y_label = np_utils.to_categorical(y_label, num_classes)
97
98 #划分训练集和验证集
99 train_paths, val_paths, y_train_label, y_val_label = train_test_split(train_paths, y_label, test_size=0.2, stratify=y_label,random_state=2019)
100
101 train_generator = get_train_batch(train_paths,batch_size = batch_size,Width = Width, Height = Height)
102 val_generator = get_train_batch(val_paths,batch_size = batch_size,Width = Width, Height = Height)
103
104 #模型定义
105 def RMB_model():
106 RMB_input = Input(shape = (Height,Width,channel), name = 'rmb_input')
107 x = Lambda(lambda x: x / 255.0)(RMB_input) # 在模型里进行归一化预处理
108 x = Conv2D(16,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv1_1')(x) #
109 x = BatchNormalization(name = 'bn_1')(x)
110 x = Conv2D(16,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv1_2')(x)
111 x = BatchNormalization(name='bn_2')(x)
112 x = MaxPooling2D((2,2),strides = (2,2),name = 'pool1')(x)
113
114 x = Conv2D(32,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv2_1')(x) #
115 x = BatchNormalization(name = 'bn_3')(x)
116 x = Conv2D(32,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv2_2')(x)
117 x = BatchNormalization(name='bn_4')(x)
118 x = MaxPooling2D((2,2),strides = (2,2),name = 'pool2')(x)
119
120 x = Conv2D(64,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv3_1')(x) #
121 x = BatchNormalization(name = 'bn_5')(x)
122 x = Conv2D(64,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv3_2')(x)
123 x = BatchNormalization(name='bn_6')(x)
124 x = MaxPooling2D((2,2),strides = (2,2),name = 'pool3')(x)
125
126 x = Conv2D(128,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv4_1')(x) #
127 x = BatchNormalization(name = 'bn_7')(x)
128 x = Conv2D(128,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv4_2')(x)
129 x = BatchNormalization(name='bn_8')(x)
130 x = MaxPooling2D((2,2),strides = (2,2),name = 'pool4')(x)
131
132 x = Conv2D(256,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv5_1')(x) #
133 x = BatchNormalization(name = 'bn_9')(x)
134 x = Conv2D(256,kernel_size = 3,strides = 1,activation = 'relu',padding = 'same',name = 'conv5_2')(x)
135 x = BatchNormalization(name='bn_10')(x)
136 x = MaxPooling2D((2,2),strides = (2,2),name = 'pool5')(x)
137
138 x = Flatten()(x)
139 x = Dense(512,activation = 'relu',name = 'fc')(x)
140 output = Dense(num_classes, activation = 'softmax',name = 'output')(x)
141
142 model = Model(inputs = RMB_input,outputs = output)
143 model.summary()
144 return model
145
146 model = RMB_model()
147 checkpointer = ModelCheckpoint(filepath='../model/best_RMB_model.hdf5',
148 monitor = 'val_acc',
149 verbose=1, save_best_only=True)
150 reduce = ReduceLROnPlateau(monitor='val_auc',factor=0.5,patience=1,verbose=1,mode='max')
151
152 adam = Adam(0.00001)
153 model.compile(optimizer = adam,
154 loss='categorical_crossentropy',
155 metrics=['accuracy'])
156
157 history = model.fit_generator(train_generator,
158 steps_per_epoch = math.ceil(len(train_paths) / batch_size),
159 epochs=epochs,
160 validation_data=val_generator,
161 validation_steps = math.ceil(len(val_paths) / batch_size),
162 callbacks=[checkpointer,reduce], verbose=1)
163
164 #预测并提交
165 def get_test_img(img_paths,Width,Height):
166 X = np.zeros((len(img_paths), Height, Width, channel), dtype=np.uint8)
167 i = 0
168 for img_path in img_paths:
169 img = Image.open(img_path)
170 img = img.convert('RGB')
171 img = img.resize((Width, Height), Image.LANCZOS)
172 arr = np.asarray(img)
173 X[i, :, :, :] = arr
174 i = i + 1
175 return X
176
177 def get_test_batch(X_path, batch_size, Width,Height):
178
179 while 1:
180 for i in range(0, len(X_path), batch_size):
181 X = get_test_img(X_path[i:i+batch_size], Width,Height)
182 yield X
183
184 model.load_weights('../model/best_RMB_model.hdf5')
185 test_generator = get_test_batch(test_paths, batch_size = batch_size, Width = Width, Height = Height)
186 pred = model.predict_generator(test_generator,steps=math.ceil(len(test_paths)/batch_size),verbose=1)
187 print(pred)
188 print(pred.shape)
189
190 index_list = np.argmax(pred,axis = 1)
191
192 label_list = []
193 for i in range(0,len(index_list)):
194 label_list.append(key_value2[index_list[i]])
195 label_list = np.array(label_list)
196
197 test_files = os.listdir(test_data_path)
198 new_test_files = []
199 for file in test_files:
200 new_test_files.append(file)
201 DataFrame_test =pd.DataFrame({'name':new_test_files,'label':label_list.reshape(-1,)})
202 DataFrame_test.to_csv('../output/submit_one_stage.csv', index = None)
203
204 print('Done')
-- 插入 --