Skip to content

Commit 2ceae9a

Browse files
authored
Add files via upload
1 parent 4ef2e21 commit 2ceae9a

File tree

1 file changed

+275
-0
lines changed

1 file changed

+275
-0
lines changed
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Created on Wed Jul 7 18:54:36 2021
4+
@author: xiuzhang CSDN
5+
参考:刘润森老师博客 推荐大家关注 很厉害的一位CV大佬
6+
https://maoli.blog.csdn.net/article/details/117688738
7+
"""
8+
import numpy as np
9+
import pandas as pd
10+
from IPython.display import display
11+
import csv
12+
from PIL import Image
13+
from scipy.ndimage import rotate
14+
15+
#----------------------------------------------------------------
16+
# 第一步 读取数据
17+
#----------------------------------------------------------------
18+
#训练数据images和labels
19+
letters_training_images_file_path = "dataset/csvTrainImages 13440x1024.csv"
20+
letters_training_labels_file_path = "dataset/csvTrainLabel 13440x1.csv"
21+
#测试数据images和labels
22+
letters_testing_images_file_path = "dataset/csvTestImages 3360x1024.csv"
23+
letters_testing_labels_file_path = "dataset/csvTestLabel 3360x1.csv"
24+
25+
#加载数据
26+
training_letters_images = pd.read_csv(letters_training_images_file_path, header=None)
27+
training_letters_labels = pd.read_csv(letters_training_labels_file_path, header=None)
28+
testing_letters_images = pd.read_csv(letters_testing_images_file_path, header=None)
29+
testing_letters_labels = pd.read_csv(letters_testing_labels_file_path, header=None)
30+
print("%d个32x32像素的训练阿拉伯字母图像" % training_letters_images.shape[0])
31+
print("%d个32x32像素的测试阿拉伯字母图像" % testing_letters_images.shape[0])
32+
print(training_letters_images.head())
33+
print(np.unique(training_letters_labels))
34+
35+
36+
#----------------------------------------------------------------
37+
# 第二步 数值转换为图像特征
38+
#----------------------------------------------------------------
39+
#原始数据集被反射使用np.flip翻转它 通过rotate旋转从而获得更好的图像
40+
def convert_values_to_image(image_values, display=False):
41+
#转换成32x32
42+
image_array = np.asarray(image_values)
43+
image_array = image_array.reshape(32,32).astype('uint8')
44+
#翻转+旋转
45+
image_array = np.flip(image_array, 0)
46+
image_array = rotate(image_array, -90)
47+
#图像显示
48+
new_image = Image.fromarray(image_array)
49+
if display == True:
50+
new_image.show()
51+
return new_image
52+
53+
#convert_values_to_image(training_letters_images.loc[0], True)
54+
55+
56+
#----------------------------------------------------------------
57+
# 第三步 图像标准化处理
58+
#----------------------------------------------------------------
59+
training_letters_images_scaled = training_letters_images.values.astype('float32')/255
60+
training_letters_labels = training_letters_labels.values.astype('int32')
61+
testing_letters_images_scaled = testing_letters_images.values.astype('float32')/255
62+
testing_letters_labels = testing_letters_labels.values.astype('int32')
63+
print("Training images of letters after scaling")
64+
print(training_letters_images_scaled.shape)
65+
print(training_letters_images_scaled[0:5])
66+
67+
68+
#----------------------------------------------------------------
69+
# 第四步 输出One-hot编码转换
70+
#----------------------------------------------------------------
71+
import keras
72+
from keras.utils import to_categorical
73+
number_of_classes = 28
74+
training_letters_labels_encoded = to_categorical(training_letters_labels-1,
75+
num_classes=number_of_classes)
76+
testing_letters_labels_encoded = to_categorical(testing_letters_labels-1,
77+
num_classes=number_of_classes)
78+
print(training_letters_labels)
79+
print(training_letters_labels_encoded)
80+
print(training_letters_images_scaled.shape)
81+
# (13440, 1024)
82+
83+
84+
#----------------------------------------------------------------
85+
# 第五步 形状修改
86+
#----------------------------------------------------------------
87+
#输入形状 32x32x1
88+
training_letters_images_scaled = training_letters_images_scaled.reshape([-1, 32, 32, 1])
89+
testing_letters_images_scaled = testing_letters_images_scaled.reshape([-1, 32, 32, 1])
90+
print(training_letters_images_scaled.shape,
91+
training_letters_labels_encoded.shape,
92+
testing_letters_images_scaled.shape,
93+
testing_letters_labels_encoded.shape)
94+
# (13440, 32, 32, 1) (13440, 28) (3360, 32, 32, 1) (3360, 28)
95+
96+
97+
#----------------------------------------------------------------
98+
# 第六步 CNN模型设计
99+
#----------------------------------------------------------------
100+
from keras.models import Sequential
101+
from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D, BatchNormalization, Dropout, Dense
102+
103+
#定义模型
104+
def create_model(optimizer='adam', kernel_initializer='he_normal', activation='relu'):
105+
#第一个卷积层
106+
model = Sequential()
107+
model.add(Conv2D(filters=16, kernel_size=3, padding='same', input_shape=(32, 32, 1), kernel_initializer=kernel_initializer, activation=activation))
108+
model.add(BatchNormalization())
109+
model.add(MaxPooling2D(pool_size=2))
110+
model.add(Dropout(0.2))
111+
112+
#第二个卷积层
113+
model.add(Conv2D(filters=32, kernel_size=3, padding='same', kernel_initializer=kernel_initializer, activation=activation))
114+
model.add(BatchNormalization())
115+
model.add(MaxPooling2D(pool_size=2))
116+
model.add(Dropout(0.2))
117+
118+
#第三个卷积层
119+
model.add(Conv2D(filters=64, kernel_size=3, padding='same', kernel_initializer=kernel_initializer, activation=activation))
120+
model.add(BatchNormalization())
121+
model.add(MaxPooling2D(pool_size=2))
122+
model.add(Dropout(0.2))
123+
124+
#第四个卷积层
125+
model.add(Conv2D(filters=128, kernel_size=3, padding='same', kernel_initializer=kernel_initializer, activation=activation))
126+
model.add(BatchNormalization())
127+
model.add(MaxPooling2D(pool_size=2))
128+
model.add(Dropout(0.2))
129+
model.add(GlobalAveragePooling2D())
130+
131+
#全连接层输出28类结果
132+
model.add(Dense(28, activation='softmax'))
133+
134+
#损失函数定义
135+
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer=optimizer)
136+
return model
137+
138+
#创建模型
139+
model = create_model(optimizer='Adam', kernel_initializer='uniform', activation='relu')
140+
model.summary()
141+
142+
143+
#----------------------------------------------------------------
144+
# 第七步 模型绘制
145+
#----------------------------------------------------------------
146+
from keras.utils.vis_utils import plot_model
147+
from IPython.display import Image as IPythonImage
148+
149+
plot_model(model, to_file="model.png", show_shapes=True)
150+
display(IPythonImage('model.png'))
151+
152+
153+
#----------------------------------------------------------------
154+
# 第八步 模型训练+输出结果
155+
#----------------------------------------------------------------
156+
from keras.callbacks import ModelCheckpoint
157+
from sklearn.metrics import classification_report
158+
import matplotlib.pyplot as plt
159+
160+
#绘制图形
161+
def plot_loss_accuracy(history):
162+
# Loss
163+
plt.figure(figsize=[8,6])
164+
plt.plot(history.history['loss'],'r',linewidth=3.0)
165+
plt.plot(history.history['val_loss'],'b',linewidth=3.0)
166+
plt.legend(['Training loss', 'Validation Loss'],fontsize=18)
167+
plt.xlabel('Epochs ',fontsize=16)
168+
plt.ylabel('Loss',fontsize=16)
169+
plt.title('Loss Curves',fontsize=16)
170+
171+
# Accuracy
172+
plt.figure(figsize=[8,6])
173+
plt.plot(history.history['accuracy'],'r',linewidth=3.0)
174+
plt.plot(history.history['val_accuracy'],'b',linewidth=3.0)
175+
plt.legend(['Training Accuracy', 'Validation Accuracy'],fontsize=18)
176+
plt.xlabel('Epochs ',fontsize=16)
177+
plt.ylabel('Accuracy',fontsize=16)
178+
plt.title('Accuracy Curves',fontsize=16)
179+
180+
#混淆矩阵
181+
def get_predicted_classes(model, data, labels=None):
182+
image_predictions = model.predict(data)
183+
predicted_classes = np.argmax(image_predictions, axis=1)
184+
true_classes = np.argmax(labels, axis=1)
185+
return predicted_classes, true_classes, image_predictions
186+
187+
def get_classification_report(y_true, y_pred):
188+
print(classification_report(y_true, y_pred, digits=4)) #小数点4位
189+
190+
checkpointer = ModelCheckpoint(filepath='weights.hdf5',
191+
verbose=1,
192+
save_best_only=True)
193+
flag = "test"
194+
if flag=="train":
195+
history = model.fit(training_letters_images_scaled,
196+
training_letters_labels_encoded,
197+
validation_data=(testing_letters_images_scaled,
198+
testing_letters_labels_encoded),
199+
epochs=20,
200+
batch_size=128,
201+
verbose=1,
202+
callbacks=[checkpointer])
203+
print(history)
204+
plot_loss_accuracy(history)
205+
else:
206+
#加载具有最佳验证损失的模型
207+
model.load_weights('weights.hdf5')
208+
metrics_ = model.evaluate(testing_letters_images_scaled,
209+
testing_letters_labels_encoded,
210+
verbose=1)
211+
print("Test Accuracy: {}".format(metrics_[1]))
212+
print("Test Loss: {}".format(metrics_[0]))
213+
214+
y_pre_test, y_true, image_predictions = get_predicted_classes(model,
215+
testing_letters_images_scaled,
216+
testing_letters_labels_encoded)
217+
get_classification_report(y_true, y_pre_test)
218+
219+
#----------------------------------------------------------------
220+
# 第九步 绘制测试图像
221+
#----------------------------------------------------------------
222+
223+
224+
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
225+
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
226+
227+
228+
fig = plt.figure(0, figsize=(14,14))
229+
indices = np.random.randint(0, testing_letters_labels.shape[0], size=42)
230+
y_pred = np.argmax(model.predict(training_letters_images_scaled), axis=1)
231+
232+
for i, idx in enumerate(indices):
233+
plt.subplot(7,6,i+1)
234+
235+
image_array = training_letters_images_scaled[idx][:,:,0]
236+
image_array = np.flip(image_array, 0)
237+
image_array = rotate(image_array, -90)
238+
239+
plt.imshow(image_array, cmap='gray')
240+
plt.title("预测:{} 真实:{}".format(y_pred[idx],
241+
(training_letters_labels[idx] -1)))
242+
plt.xticks([])
243+
plt.yticks([])
244+
plt.show()
245+
plt.savefig("resutl.png", dpi=300)
246+
247+
## 评价预测效果,计算混淆矩阵
248+
import seaborn as sns
249+
from sklearn import metrics
250+
251+
Labname = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,
252+
15,16,17,18,19,20,21,22,23,24,25,26,27,28]
253+
print(y_pre_test)
254+
y_pre_test = [num+1 for num in y_pre_test]
255+
print(np.argmax(testing_letters_labels,axis=1))
256+
confm = metrics.confusion_matrix(testing_letters_labels,
257+
y_pre_test)
258+
print(confm.T)
259+
260+
plt.figure(figsize=(10,10))
261+
heatmap = sns.heatmap(confm.T, square=True, annot=True,
262+
fmt='d', cbar=True, linewidths=.6,
263+
cmap="YlGnBu")
264+
bottom, top = heatmap.get_ylim()
265+
heatmap.set_ylim(bottom + 0.5, top - 0.5)
266+
plt.xlabel('True label',size = 12)
267+
plt.ylabel('Predicted label', size = 12)
268+
#plt.xticks(np.arange(28)+0.5, Labname, size = 10)
269+
#plt.yticks(np.arange(28)+0.5, Labname, size = 10)
270+
plt.savefig('headmap.png', dpi=300)
271+
plt.show()
272+
273+
274+
275+

0 commit comments

Comments
 (0)