学习最好的办法就是实践。
深度学习有很多入门的数据集,手写数字数据集是其中一个代表。
以Kannada-MNIST为例:我们做一个手写数字识别的程序。
引入pandas,做数据预处理用的。
import pandas as pd
加载训练数据
train_data = pd.read_csv("/kaggle/input/Kannada-MNIST/train.csv")
加载测试数据
test_data = pd.read_csv("/kaggle/input/Kannada-MNIST/test.csv")
取出训练数据的标签
train_y = train_data["label"]
取出训练数据的样本
train_x = train_data.drop(labels = ["label"], axis = 1)
把数据reshape成28*28的图像
train_x = np.array(train_x).reshape(-1,28,28,1)
把数据做一个归一化,成0~1之间的数
train_x = train_x/255
引入图像绘制库
import matplotlib.pyplot as plt
显示第一张训练数据的图像
g = plt.imshow(train_x[0][:,:,0])
引入一堆keras的API
模型容器
from keras.models import Sequential
全连接,卷积,若干优化算法
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D, BatchNormalization
梯度算法优化器
from keras.optimizers import Adam
数据增强
from keras.preprocessing.image import ImageDataGenerator
动态调整学习率
from keras.callbacks import ReduceLROnPlateau
算法模型
容器
model = Sequential()
卷积
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu',input_shape = (28,28,1)))
归一化
model.add(BatchNormalization())
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu'))
model.add(BatchNormalization())
池化层
model.add(MaxPool2D(pool_size=(2,2)))
丢弃部分参数
model.add(Dropout(0.36))
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu'))
model.add(BatchNormalization())
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu'))
model.add(BatchNormalization())
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.36))
model.add(Conv2D(filters=64,kernel_size=(5,5),padding='Same',activation='relu'))
model.add(BatchNormalization())
拉直
model.add(Flatten())
全连接
model.add(Dense(512,activation='relu'))
model.add(Dense(64,activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.25))
多分类
model.add(Dense(10, activation = "softmax"))
打印出模型
from keras.utils import plot_model
plot_model(model, to_file='model.png', show_shapes=True, show_layer_names=True)
from IPython.display import Image
Image("model.png")
from keras.optimizers import Adam
# 定义Optimizer
optimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
# 编译model
model.compile(optimizer = optimizer , loss = "categorical_crossentropy", metrics=["accuracy"])
# 设置学习率的动态调整
learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc',
patience=3,
verbose=1,
factor=0.5,
min_lr=0.00001)
epochs = 50
batch_size = 128
# 通过数据增强来防止过度拟合
datagen = ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range=10, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range = 0.1, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip=False, # randomly flip images
vertical_flip=False) # randomly flip images
datagen.fit(train_x)
# 训练模型
history = model.fit_generator(datagen.flow(train_x,train_y, batch_size=batch_size),
epochs = epochs, validation_data = (val_x,val_y),
verbose = 2, steps_per_epoch=train_x.shape[0] // batch_size
, callbacks=[learning_rate_reduction])
# 画训练集和验证集的loss和accuracy曲线。可以判断是否欠拟合或过拟合 fig, ax = plt.subplots(2,1) ax[0].plot(history.history['loss'], color='b', label="Training loss") ax[0].plot(history.history['val_loss'], color='r', label="validation loss",axes =ax[0]) legend = ax[0].legend(loc='best', shadow=True) ax[1].plot(history.history['acc'], color='b', label="Training accuracy") ax[1].plot(history.history['val_acc'], color='r',label="Validation accuracy") legend = ax[1].legend(loc='best', shadow=True)
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
import itertools
# 画出混淆矩阵,可以用来观察误判比较高的情况
def plot_confusion_matrix(cm, classes,
normalize=False,
title='Confusion matrix',
cmap=plt.cm.Blues):
"""
This function prints and plots the confusion matrix.
Normalization can be applied by setting `normalize=True`.
"""
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, cm[i, j],
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label')
# Predict the values from the validation dataset
Y_pred = model.predict(val_x)
# Convert predictions classes to one hot vectors
Y_pred_classes = np.argmax(Y_pred,axis = 1)
# Convert validation observations to one hot vectors
Y_true = np.argmax(val_y,axis = 1)
# compute the confusion matrix
confusion_mtx = confusion_matrix(Y_true, Y_pred_classes)
# plot the confusion matrix
plot_confusion_matrix(confusion_mtx, classes = range(10))
# 显示一些错误结果,及预测标签和真实标签之间的不同
errors = (Y_pred_classes - Y_true != 0)
Y_pred_classes_errors = Y_pred_classes[errors]
Y_pred_errors = Y_pred[errors]
Y_true_errors = Y_true[errors]
X_val_errors = val_x[errors]
def display_errors(errors_index,img_errors,pred_errors, obs_errors):
""" This function shows 6 images with their predicted and real labels"""
n = 0
nrows = 2
ncols = 3
fig, ax = plt.subplots(nrows,ncols,sharex=True,sharey=True)
for row in range(nrows):
for col in range(ncols):
error = errors_index[n]
ax[row,col].imshow((img_errors[error]).reshape((28,28)))
ax[row,col].set_title("Predicted label :{}\nTrue label :{}".format(pred_errors[error],obs_errors[error]))
n += 1
# Probabilities of the wrong predicted numbers
Y_pred_errors_prob = np.max(Y_pred_errors,axis = 1)
# Predicted probabilities of the true values in the error set
true_prob_errors = np.diagonal(np.take(Y_pred_errors, Y_true_errors, axis=1))
# Difference between the probability of the predicted label and the true label
delta_pred_true_errors = Y_pred_errors_prob - true_prob_errors
# Sorted list of the delta prob errors
sorted_dela_errors = np.argsort(delta_pred_true_errors)
# Top 6 errors
most_important_errors = sorted_dela_errors[-6:]
# Show the top 6 errors
display_errors(most_important_errors, X_val_errors, Y_pred_classes_errors, Y_true_errors)