# 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)
```