# Image Classification - Evaluate tool ## Plot Function ### 定義類別 ```python= class_names = ['normal', 'abnormal'] ``` ### 載入圖片轉np格式 ```python= import tensorflow as tf from tensorflow.keras.models import Model from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.xception import preprocess_input def load_image(path, img_shape): img = image.load_img(path, target_size=img_shape) x = image.img_to_array(img) imgg =x.astype('uint8') x = np.expand_dims(x, axis=0) x = preprocess_input(x) return x, imgg ``` ### 畫測試圖 ```python= def plot_image(i, predictions_array, true_label, img, img_id): #true_label, img = true_label[i], img[i] true_label = true_label img = img plt.grid(False) plt.xticks([]) plt.yticks([]) plt.imshow(img, cmap=plt.cm.binary) predicted_label = np.argmax(predictions_array) if predicted_label == true_label: color = 'blue' else: color = 'red' plt.xlabel("{} {:2.0f}% ({}) \nid: ({})".format(class_names[predicted_label], 100*np.max(predictions_array), class_names[true_label], img_id), color=color) ``` ### 畫機率值 ```python= def plot_value_array(i, predictions_array, true_label): true_label = true_label plt.grid(False) plt.xticks(range(2)) plt.yticks([]) thisplot = plt.bar(range(2), predictions_array, width=0.3, color="#777777") plt.ylim([0, 1]) predicted_label = np.argmax(predictions_array) thisplot[predicted_label].set_color('red') thisplot[true_label].set_color('blue') ``` ### 畫grad cam或者grad cam ++ * grad_cam * grad_cam_plus 詳細請參考:https://hackmd.io/@JackyYen/BkOvDp8PY ```python= def plot_gram(i, img_path, img_shape, input_model, layer_name): preprocessed_input, img = load_image(img_path, img_shape) predictions = input_model.predict(preprocessed_input) predicted_class = np.argmax(predictions) #cam, heatmap = grad_cam(input_model, img, img_shape, predicted_class, layer_name) cam = grad_cam_plus(input_model, img, img_shape, predicted_class, layer_name) overcam = cv2.addWeighted(img, 0.8, cam, 0.3, 0) #cv2.imwrite(os.path.join(cam_path, each), overcam) #plt.figure(figsize=(5, 5)) plt.grid(False) plt.xticks([]) plt.yticks([]) plt.imshow(overcam[:,:,[ 2, 1, 0]]) #plt.axis("off") ``` ### 畫lime 詳細請參考:https://hackmd.io/@JackyYen/BkOvDp8PY ```python= import lime from lime import lime_image import skimage.io as io from skimage import transform from skimage import img_as_float from skimage.segmentation import mark_boundaries from tensorflow.keras.preprocessing import image def plot_lime(i, img_path, img_shape, input_model): preprocessed_input, img = load_image(img_path, img_shape) explainer = lime_image.LimeImageExplainer() x = preprocessed_input[0].astype(np.double) explanation = explainer.explain_instance( x, input_model.predict, top_labels=5, hide_color=0, num_samples=1000 ) #print(explanation) temp, mask = explanation.get_image_and_mask( explanation.top_labels[0], positive_only=True, negative_only=False, num_features=5, hide_rest=False ) img = io.imread(img_path) img = transform.resize(img, img_shape) image = img_as_float(img) plt.grid(False) plt.xticks([]) plt.yticks([]) #plt.axis("off") plt.imshow(mark_boundaries(image,mask)) #plt.imsave("out.jpg",mark_boundaries(image,mask)) ``` ### plot_gram subfunction #### Grad Cam ```python= def grad_cam(input_model, image, img_shape, category_index, layer_name): grad_model = Model(input_model.inputs, [input_model.get_layer(layer_name).output, model.output]) with tf.GradientTape() as tape: conv_outputs, predictions = grad_model(np.array([image])) loss = predictions[:, category_index] output = conv_outputs[0] grads = tape.gradient(loss, conv_outputs)[0] grads_val = grads.numpy() weights = np.mean(grads_val, axis = (0, 1)) cam = np.dot(output.numpy(), weights) cam = cv2.resize(cam, img_shape) #relu max_cam = np.maximum(cam, 0) if np.max(max_cam) == 0: max_cam[max_cam==0] = 1e-10 #normalize cam = cam/np.max(max_cam) cam = cv2.applyColorMap(np.uint8(255 * cam), cv2.COLORMAP_JET) return cam #, heatmap ``` #### Grad Cam++ ```python= def grad_cam_plus(input_model, image, img_shape, category_index, layer_name): grad_model = Model(input_model.inputs, [input_model.get_layer(layer_name).output, model.output]) with tf.GradientTape() as gtape1: with tf.GradientTape() as gtape2: with tf.GradientTape() as gtape3: conv_output, predictions = grad_model(np.array([image])) output = predictions[:, category_index] conv_first_grad = gtape3.gradient(output, conv_output) conv_second_grad = gtape2.gradient(conv_first_grad, conv_output) conv_third_grad = gtape1.gradient(conv_second_grad, conv_output) global_sum = np.sum(conv_output, axis=(0, 1, 2)) alpha_num = conv_second_grad[0] alpha_denom = conv_second_grad[0]*2.0 + conv_third_grad[0]*global_sum alpha_denom = np.where(alpha_denom != 0.0, alpha_denom, 1e-10) alphas = alpha_num/alpha_denom alpha_normalization_constant = np.sum(alphas, axis=(0,1)) alphas /= alpha_normalization_constant weights = np.maximum(conv_first_grad[0], 0.0) deep_linearization_weights = np.sum(weights*alphas, axis=(0,1)) grad_CAM_map = np.sum(deep_linearization_weights*conv_output[0], axis=2) heatmap = np.maximum(grad_CAM_map, 0) max_heat = np.max(heatmap) if max_heat == 0: max_heat = 1e-10 heatmap /= max_heat heatmap = cv2.resize(heatmap, (image.shape[1], image.shape[0])) heatmap = (heatmap*255).astype("uint8") heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) return heatmap ``` ## 畫 測試圖+gradcam/lime+機率圖 ```python= num_rows = 10 num_cols = 3 num_images = num_rows*num_cols n = 3 plt.figure(figsize=(n*n*num_cols, n*num_rows)) class_names = ['normal', 'abnormal'] #j = 0 start = (y_test_cat.shape[0]//num_images) for j in range(0, start+1): print('批次: ', j) print('range: ', num_images*j,' ~ ', num_images*(j+1)) plt.figure(figsize=(n*n*num_cols, n*num_rows)) for i in range(num_images*j, num_images*(j+1), 1): print('processing: ', i+1, '/', num_images) #print('----',n*i+1,'----',n*(i- (num_images*j)) + 1,'----',n*(i- (num_images*j)) + 2, '----',n*(i- (num_images*j)) + 3) if i == (y_test_cat.shape[0]): print('-----Stop-----') print('i: ',i) print('---Complete---') break plt.subplot(num_rows, n*num_cols, n*(i- (num_images*j)) + 1) plot_image(i, y_predict[i], y_test[i], test_view[0][0][i], x_test[i]) plt.subplot(num_rows, n*num_cols, n*(i- (num_images*j)) + 2) plot_lime(i, x_test[i], test_generator[0][0][i].shape[0:2], model) #plot_gram(i, x_test[i], test_generator[0][0][i].shape[0:2], model, layer_name) plt.subplot(num_rows, n*num_cols, n*(i- (num_images*j)) + 3) plot_value_array(i, y_predict[i], y_test[i]) plt.tight_layout() plt.savefig('./results_lime/xception/all/xception'+str(j+1)+'.png') plt.show() ``` ## 畫判斷錯誤圖 記下有錯的位址 ```python= import numpy as np import matplotlib.pyplot as plt index = 0 misclassifiedIndexes = [] for label, predict in zip(y_test, y_predict_argmax): if label != predict: misclassifiedIndexes.append(index) index +=1 ``` ### 錯誤樣本+機率圖(可修改) ```python= # Plot the first X test images, their predicted labels, and the true labels. # Color correct predictions in blue and incorrect predictions in red. num_rows = 10 num_cols = 4 num_images = num_rows*num_cols plt.figure(figsize=(2*2*num_cols, 2*num_rows)) class_names = ['normal', 'abnormal'] #j = 0 start = (len(misclassifiedIndexes)//num_images) for j in range(0, start+1): print('批次: ', j) print('range: ', num_images*j,' ~ ', num_images*(j+1)) plt.figure(figsize=(2*2*num_cols, 2*num_rows)) for i in range(num_images*j, num_images*(j+1), 1): print('processing: ', i+1, '/', num_images) if i == (len(misclassifiedIndexes)): print('-----Stop-----') print('*'*15,'\n') print('*'*15,'\n') print('---Complete---') break print('*'*15) print('misclassifiedIndexes: ',misclassifiedIndexes[i]) print('*'*15,'\n') idx = misclassifiedIndexes[i] plt.subplot(num_rows, 2*num_cols, 2*(i- (num_images*j)) + 1) plot_image(i, y_predict[idx], y_test[idx], test_generator[0][0][idx], x_test[idx].split('\\')[1]) plt.subplot(num_rows, 2*num_cols, 2*(i- (num_images*j)) + 2) plot_value_array(i, y_predict[idx], y_test[idx]) plt.tight_layout() plt.savefig('./results/xception/wrong/xception_錯的_'+str(j+1)+'.png') plt.show() ``` ## 指標分析 ### Confusion matrix ```python= import seaborn as sns import pandas as pd target_names = ['normal', 'abnormal'] conf_m = pd.DataFrame(cm, index = target_names, columns = target_names) fig, ax = plt.subplots(figsize = (8, 6)) sns.heatmap(conf_m, annot=True, annot_kws={"size": 20}, cmap='Blues_r', fmt='g', linewidth=0.5, square=True) plt.ylabel('True label', fontsize=18) plt.xlabel('Pred label', fontsize=18) plt.yticks(fontsize=18) plt.xticks(fontsize=18) plt.savefig('./results/xception/xception_cm.png', bbox_inches='tight') plt.show() ``` ### metrics report ```python= from sklearn.metrics import classification_report report = classification_report(np.argmax(test_generator[0][1], axis=1), y_predict_argmax, target_names=target_names) print(report) ```