作为深度学习的入门,先来讲一下简单的猫狗分类。
深度学习:训练数据集,让计算机精准识别这个是猫还是狗。
猫狗识别:
1、数据预处理:准备训练集和测试集
2、卷积神经网络模型:构建网络架构
3、数据增强:图像数据增强方法与效果
4、迁移学习
准备数据
在当前py文件所在位置创建一个data文件夹,里面放入train、test俩个子文件夹,train和test中放入收集到的猫和狗图片,注意图片大小要归一化,这里将其改为64*64。
#数据所在文件夹
base_dir = './data'
train_dir = os.path.join(base_dir,'train')
test_dir = os.path.join(base_dir,'test')
#训练集
train_cats_dir = os.path.join(train_dir,'cats')
train_dogs_dir = os.path.join(train_dir,'dogs')
#测试集
test_cats_dir = os.path.join(test_dir,'cats')
test_dogs_dir = os.path.join(test_dir,'dogs')
构建卷积神经网络模型
model = Sequential()
model.add(Conv2D(filters=6, kernel_size=(5, 5), padding='same', input_shape=(64,64,3), activation='tanh'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=16, kernel_size=(5, 5), padding='same', activation='tanh'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten()) #为全连接层准备,把特征图拉成一个向量
model.add(Dense(120, activation='tanh'))
model.add(Dense(84, activation='tanh'))
model.add(Dense(1, activation='sigmoid'))
sgd = SGD(lr=0.001, decay=1e-6, momentum=0.9, nesterov=True)
filiters:特征图的个数,filiters个不同的卷积核
kernel_size:卷积核尺寸
padding:填充,same保证输出特征图大小和输入相等
strides:步长,不写默认为1
输入model.summary()可以查看模型参数
卷积核的第三个维度和输入图像的第三个维度一致。
灰度图为1,RGB图像为3。
配置训练器
model.compile(optimizer=sgd, loss='binary_crossentropy', metrics=['accuracy'])
数据预处理
读入的数据自动转化为tensor(float32)格式,分别准备训练和测试。
图像数据归一化(0-1),这边类似为手写数据集的预处理。
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_dir, #文件夹路径
target_size = (64,64), #指定resize成的大小
batch_size = 32,
class_mode='binary')
test_generator = test_datagen.flow_from_directory(
test_dir, #文件夹路径
target_size = (64,64), #指定resize成的大小
batch_size = 32,
class_mode='binary')
图像生成器:告诉机器到哪里去一个batch一个batch的读取数据。
训练网络模型
fit_generator相当于一个生成器,动态产生所需要的batch数据
steps_per_epoch相当于给定一个停止条件。
history = model.fit_generator(
train_generator,
step_per_epoch = 100,
epoch = 20,
test_data = test_generator,
test_steps = 50,
verbose=2)
当然也可以用softmax进行二分类,具体代码如下:
第一步:打标签,关于如何打标签,先看上一篇博文。
data = []
labels = []
# 拿到图像数据路径,方便后续读取
imagePaths = sorted(list(utils_paths.list_images('./dataset')))
random.seed(42)
random.shuffle(imagePaths)
# 遍历读取数据
for imagePath in imagePaths:
# 读取图像数据
image = cv2.imread(imagePath,1) #读取灰度图像
image = cv2.resize(image, (96, 96))
data.append(image)
# 读取标签
label = imagePath.split(os.path.sep)[-2] #文件路径的倒数第二个就是文件夹的名字被定义为标签
labels.append(label)
# 对图像数据做scale操作
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)
print(labels)
# 数据集切分
(trainX, testX, trainY, testY) = train_test_split(data,labels, test_size=0.2, random_state=42)
from keras.utils import to_categorical
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
trainY1 = to_categorical(trainY, 2)#修改
testY = lb.transform(testY)
testY1 = to_categorical(testY,2)
第二步,构建模型,和上文一致,这里不过多阐述了。
第三部,训练模型并输出相关评价指标。
from sklearn.metrics import precision_score,recall_score,f1_score,roc_auc_score,roc_curve,auc,plot_roc_curve
import numpy as np
from sklearn.metrics import accuracy_score
y_true = np.argmax(testY1, axis=1)
print(y_true) #one-hot编码: 0表示为:10(两个状态位)
#y_true = list(np.concatenate(testY.reshape((-1, 1), order="F")))
y_pred1 = model.predict(testX)
print(y_pred1)
#y_pred = model.predict_classes(testX)
#y_pred = list(np.concatenate(y_pred.reshape((-1, 1), order="F")))
y_pred = np.argmax(y_pred1, axis=1)
print(y_true)
print(y_pred)
accuracy = accuracy_score(y_true, y_pred)
print('Accuracy: {}%'.format(accuracy * 100))
print('Error rate: {:.2f}%'.format((1 - accuracy) * 100))
#plot_roc_curve(y_true, y_probas)
#print('accuracy_score: {:.2f}'.format(accuracy_score(y_true, y_pred)))
print('precision_score: {:.2f}'.format(precision_score(y_true, y_pred)))
print('recall_score: {:.2f}'.format(recall_score(y_true, y_pred)))
print('f1_score: {:.2f}'.format(f1_score(y_true, y_pred)))
from sklearn.metrics import confusion_matrix
confusion_matrix(y_true, y_pred)
#print(np.confusion_matrix)
import seaborn as sn
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6),dpi=100)
sn.heatmap(confusion_matrix(y_true, y_pred), annot=True)
plt.show()
# 绘制Roc
y_pred_keras = model.predict(testX)[:, 1]
#y_pred_keras = model.predict_proba(testX)[:, 1]
print(y_pred_keras.shape)
#y_pred_keras= [0.54, 0.567]
fpr, tpr, thresholds = roc_curve(y_true,y_pred_keras)
roc_auc = auc(fpr, tpr)
plt.title('Receiver Operating Characteristic')
plt.plot(fpr, tpr, '#9400D3',label=u'AUC = %0.3f'% roc_auc)
plt.legend(loc='lower right')
plt.plot([0,1],[0,1],'r--')
plt.xlim([-0.1,1.1])
plt.ylim([-0.1,1.1])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.grid(linestyle='-.')
plt.grid(True)
plt.show()
print(roc_auc)
PR曲线
y_pred_keras = y_pred1[:, 1]
print(y_pred1)
print(y_pred_keras)
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve,auc
precision, recall, thresholds=precision_recall_curve(y_true, y_pred_keras)
pr_auc=auc(recall, precision)
plt.plot(precision, recall,'#9400D3', label=u'AUC = %0.4f' % pr_auc)
plt.legend(loc='lower left')
#plt.plot([1,0],[0,1],'r--')
plt.ylim([-0.1, 1.1])
plt.xlim([-0.1, 1.1])
plt.ylabel('Precision')
plt.xlabel('Recall')
plt.grid(linestyle='-.')
plt.grid(True)
plt.show()
print(auc(recall, precision))
DET
import matplotlib.pyplot as plt
fpr_det, fnr_det, thresholds_det = metrics.det_curve(y_true, y_pred_keras, pos_label=1)
#FAR(FPR)
plt.title('Detection Error Tradeoff')
#display = metrics.DetCurveDisplay(fpr=fpr_det, fnr=fnr_det)
#a= compute_eer(y_true, y_pred)
#print(a)
#display = metrics.DetCurveDisplay(fpr=fpr_det, fnr=fnr_det)
#display.plot()
plt.plot(fpr_det, fnr_det)
plt.legend(loc='lower right') # 图例出现在左下角
#plt.plot([0, 1], [0, 1], 'r--')
#plt.xlim([0, 1])
#plt.ylim([0, 1])
plt.ylabel('False Rejection Rate')
plt.xlabel('False Acceptance Rate')
plt.grid(linestyle='-.')
plt.grid(True)
plt.show()