1. 绘制各种曲线
1.1 损失函数曲线
def plot_loss_cure(epoch_list, loss_list):
plt.plot(epoch_list, loss_list)
plt.xlabel('Number of Epoch')
plt.ylabel('Loss')
plt.title('RNN')
plt.savefig('rnn.png') # 保存图片
plt.show()
epoch_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
loss_list = [0.1125, 0.0307, 0.0218, 0.0172, 0.0154, 0.0138, 0.011, 0.0123, 0.0106, 0.0103]
plot_loss_cure(epoch_list, loss_list)
效果如下
1.2 准确率曲线
epoch_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
acc_list = [0.9076, 0.9517, 0.9077, 0.9662, 0.9694, 0.9685, 0.9765, 0.9711, 0.9744, 0.9790]
plot_loss_cure(epoch_list, acc_list)
效果如下:
1.3 同时画出训练集验证集准确率与损失曲线对比图
from collections import defaultdict
def plot_training_history(history):
# 按1行2列格式显示
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
ax1.plot(history['train_loss'], label='train_loss')
ax1.plot(history['val_loss'], label='val_loss')
ax1.legend()
ax1.set_ylabel('Loss')
ax1.set_xlabel('Epoch')
# ax1.set_title('Model Loss')
ax2.plot(history['train_acc'], label='train_acc')
ax2.plot(history['val_acc'], label='val_acc')
ax2.legend()
ax2.set_ylabel('Acc')
ax2.set_xlabel('Epoch')
fig.suptitle('Training History')
plt.pause(0.001)
plt.show()
调用
history = defaultdict(list) # 构建一个默认value为list的字典
train_acc = [0.9176, 0.9417, 0.9517, 0.9622, 0.9694, 0.9715, 0.9765, 0.9771, 0.9784, 0.9790]
val_acc = [0.8076, 0.8517, 0.8077, 0.8662, 0.8694, 0.8685, 0.8765, 0.8711, 0.8744, 0.8790]
train_loss = [0.1225, 0.0407, 0.0318, 0.0192, 0.0184, 0.0158, 0.0141, 0.0123, 0.0116, 0.0113]
val_loss = [0.2125, 0.2307, 0.2218, 0.2172, 0.1154, 0.1138, 0.111, 0.1123, 0.1106, 0.1103]
history['train_acc'].extend(train_acc)
history['val_acc'].extend(val_acc)
history['train_loss'].extend(train_loss)
history['val_loss'].extend(val_loss)
plot_training_history(history)
效果如下:
1.4 绘制ROC曲线
import plotly.offline as py
# py.init_notebook_mode(connected=True)
import plotly.graph_objs as go
import plotly.subplots as tls
import plotly.figure_factory as ff
from sklearn.metrics import roc_curve, roc_auc_score
def plot_roc_auc_curve(y_test, y_pred):
# y_test.squeeze() # 有时需要降维
fpr, tpr, t = roc_curve(y_test, y_pred)
model_roc_auc = roc_auc_score(y_test, y_pred)
trace = go.Scatter(x=fpr, y=tpr,
name='ROC: ' + str(model_roc_auc),
line=dict(color=('rgb(22, 96, 167)'), width=2), fill='tozeroy')
fig = tls.make_subplots(rows=1, cols=1, print_grid=False, subplot_titles=('ROC_AUC_curve',))
fig.append_trace(trace, 1, 1)
fig.layout.xaxis.update(dict(title='FPR'), range=[0, 1.05])
fig.layout.yaxis.update(dict(title='TPR', range=[0, 1.05]))
fig.layout.titlefont.size = 14
py.plot(fig)
if __name__ == '__main__':
y_test = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1]
y_pred = [1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1]
plot_roc_auc_curve(y_test, y_pred)
效果展示:
1.5 绘制混淆矩阵
from sklearn.metrics import confusion_matrix
def plot_cm(y_test, y_pred):
cm = confusion_matrix(y_test, y_pred)
trace1 = go.Heatmap(z=cm,
x=["0(pred)", "1(pred)"],
y=["0(True)", "1(True)"],
xgap=2, ygap=2,
colorscale='Viridis', showscale=False)
TP = cm[1, 1]
FN = cm[1, 0]
FP = cm[0, 1]
TN = cm[0, 0]
accuracy = (TP+TN) / (TP+TN+FP+FN)
precision = TP / (TP+FP)
recall = TP / (TP+FN)
F1_score = (2*precision*recall) / (precision+recall)
df_cm = pd.DataFrame(data=[[accuracy, precision, recall, F1_score]])
df_cm = df_cm.T
# 可视化
colors = ['gold', 'lightgreen', 'lightcoral', 'lightskyblue']
trace2 = go.Bar(x=df_cm[0].values,
y=['Accuracy', 'Precision', 'Recall', 'F1_score'],
text=np.round_(df_cm[0].values, 4),
textposition='auto',
orientation='h',
opacity=0.8,
marker=dict(color=colors, line=dict(color='#000000', width=1.5)))
fig = tls.make_subplots(rows=2, cols=1, subplot_titles=('Confusion Matrix', 'Metrics'))
fig.append_trace(trace1, 1, 1)
fig.append_trace(trace2, 2, 1)
py.plot(fig)
if __name__ == '__main__':
y_test = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1]
y_pred = [1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1]
plot_cm(y_test, y_pred)
效果展示:
2. 显示图片
2.1 绘制一张图片
方法1:
def image_show_1(img, title=None):
plt.figure(figsize=(14, 3))
img = img.numpy().transpose((1, 2, 0)) # 改变shape顺序
mean = np.array([0.485, 0.456, 0.406])
std = np.array([0.229, 0.224, 0.225])
img = img * std + mean # 逆向复原
img = np.clip(img, 0, 1) # 将元素值限制在0-1之间
plt.imshow(img)
if title is not None:
plt.title(title)
plt.pause(0.001)
plt.show()
方法2:
def image_show_2(img):
img = img / 2 + 0.5 # 逆正则化
np_img = img.numpy() # tensor --> numpy
plt.imshow(np.transpose(np_img, (1, 2, 0))) # 改变通道顺序
plt.show()
方法3: 从url读取图片
from PIL import Image
def image_show_3(img):
plt.figure(figsize=(8, 8))
plt.imshow(img)
plt.axis('off') # 关闭坐标轴
plt.show()
img = Image.open(data_loader['train'].dataset.root + '/NORMAL/IM-0117-0001.jpeg')
image_show_3(img)
2.2 以grid形式绘制一幅图片
显示一个batch_size的图片
def show_a_batch_train_data_picture(dataloaders, target_names):
datas, targets = next(iter(dataloaders['train']))
print(targets) # 需要根据target_names标签列表进行映射
# tensor([1, 0, 0, 1, 1, 0, 1, 1])
# 将若干张图片拼成一幅图像
grid = make_grid(datas, nrow=4, padding=10)
# 图片显示
image_show_1(grid, title=[target_names[x] for x in targets])
image_show_2(grid)
# 显示第6张图片
image_show_1(*data_loader['train'].dataset[5])
if __name__ == "__main__":
BATCH_SIZE = 8
DATA_PATH = '../data/chest_xray'
data_loader = load_data(DATA_PATH, BATCH_SIZE)
# 获取标签的类别名称
labels = ['NORMAL', 'PNEUMONIA']
show_a_batch_train_data_picture(data_loader, labels)