In [ ]:
#!pip install tensorflow
In [ ]:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import tensorflow as tf
from tensorflow.keras import layers, models
In [ ]:
from keras.datasets import mnist
(x_train_image,y_train_label),(x_test_image,y_test_label)=mnist.load_data()
print('train data= ',x_train_image.shape)
print('test data=', x_test_image.shape)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz 11490434/11490434 ━━━━━━━━━━━━━━━━━━━━ 1s 0us/step train data= (60000, 28, 28) test data= (10000, 28, 28)
In [ ]:
import matplotlib.pyplot as plt
# 建立函數要來畫多圖的
def plot_images_labels_prediction(images,labels,prediction,idx,num=10):
# 設定顯示圖形的大小
fig= plt.gcf()
fig.set_size_inches(12,14)
# 最多25張
if num>25:num=25
# 一張一張畫
for i in range(0,num):
# 建立子圖形5*5(五行五列)
ax=plt.subplot(5,5,i+1)
# 畫出子圖形
ax.imshow(images[idx],cmap='binary')
# 標題和label
title="label=" +str(labels[idx])
# 如果有傳入預測結果也顯示
if len(prediction)>0:
title+=",predict="+str(prediction[idx])
# 設定子圖形的標題大小
ax.set_title(title,fontsize=10)
# 設定不顯示刻度
ax.set_xticks([]);ax.set_yticks([])
idx+=1
plt.show()
plot_images_labels_prediction(x_train_image,y_train_label,[],0,10)
In [ ]:
#x_Train=x_train_image.reshape(60000,784).astype('float32')
#x_Test=x_test_image.reshape(10000,784).astype('float32')
# 由於是圖片最大的是255,所以全部除以255,使其變成0-1的數值
x_Train_normalize=x_train_image/255
x_Test_normalize=x_test_image/255
In [ ]:
# Build the CNN model
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.Flatten(),
layers.Dense(32, activation='relu'),
layers.Dense(10, activation='softmax')
])
# Compile the model
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# Train the model
history = model.fit(x_Train_normalize, y_train_label, epochs=10, validation_split=0.1)
/usr/local/lib/python3.10/dist-packages/keras/src/layers/convolutional/base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Epoch 1/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 28s 16ms/step - accuracy: 0.8523 - loss: 0.4666 - val_accuracy: 0.9808 - val_loss: 0.0674 Epoch 2/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 26s 15ms/step - accuracy: 0.9779 - loss: 0.0698 - val_accuracy: 0.9838 - val_loss: 0.0520 Epoch 3/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 41s 15ms/step - accuracy: 0.9851 - loss: 0.0477 - val_accuracy: 0.9860 - val_loss: 0.0485 Epoch 4/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 26s 16ms/step - accuracy: 0.9880 - loss: 0.0372 - val_accuracy: 0.9878 - val_loss: 0.0447 Epoch 5/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 26s 15ms/step - accuracy: 0.9914 - loss: 0.0275 - val_accuracy: 0.9863 - val_loss: 0.0527 Epoch 6/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 41s 15ms/step - accuracy: 0.9934 - loss: 0.0219 - val_accuracy: 0.9888 - val_loss: 0.0484 Epoch 7/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 41s 15ms/step - accuracy: 0.9945 - loss: 0.0169 - val_accuracy: 0.9878 - val_loss: 0.0496 Epoch 8/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 26s 16ms/step - accuracy: 0.9965 - loss: 0.0123 - val_accuracy: 0.9892 - val_loss: 0.0492 Epoch 9/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 38s 23ms/step - accuracy: 0.9969 - loss: 0.0091 - val_accuracy: 0.9882 - val_loss: 0.0522 Epoch 10/10 1688/1688 ━━━━━━━━━━━━━━━━━━━━ 27s 16ms/step - accuracy: 0.9971 - loss: 0.0080 - val_accuracy: 0.9855 - val_loss: 0.0730
In [ ]:
# Evaluate the model
test_loss, test_acc = model.evaluate(x_Test_normalize, y_test_label)
print(f"Test accuracy: {test_acc:.4f}")
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step - accuracy: 0.9834 - loss: 0.0550 Test accuracy: 0.9859
In [ ]:
fig, ax = plt.subplots(1, 2, figsize=(8, 3)) # Create a 1x2 grid of subplots
# Plot accuracy
ax[0].plot(np.arange(1,11),history.history['accuracy'], label='Training Accuracy', marker='o')
ax[0].plot(np.arange(1,11),history.history['val_accuracy'], label='Validation Accuracy', marker='x')
ax[0].set_title('Accuracy')
ax[0].set_xlabel('Epoch')
ax[0].set_ylabel('Accuracy')
ax[0].legend(loc='lower right')
ax[0].set_ylim([0.9, 1.0])
ax[0].grid(True)
# Plot loss
ax[1].plot(np.arange(1,11),history.history['loss'], label='Training Loss', marker='o')
ax[1].plot(np.arange(1,11),history.history['val_loss'], label='Validation Loss', marker='x')
ax[1].set_title('Loss')
ax[1].set_xlabel('Epoch')
ax[1].set_ylabel('Loss')
ax[1].legend(loc='upper right')
ax[1].set_ylim([0,0.2])
ax[1].grid(True)
plt.tight_layout() # Adjust subplot spacing
plt.show()
In [ ]:
from sklearn import datasets, svm, metrics
# Predict the value of the digit on the test subset
predicted = np.argmax(model.predict(x_Test_normalize), axis=1)
# Display the confusion matrix
disp = metrics.ConfusionMatrixDisplay.from_predictions(y_test_label, predicted,cmap='CMRmap_r')
accu = metrics.accuracy_score(y_test_label, predicted)
disp.figure_.suptitle("Confusion Matrix of CNN")
#print(f"Confusion matrix:\n{disp.confusion_matrix}")
print('Overall Acuracy:{:.4}'.format(accu))
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 5ms/step Overall Acuracy:0.9859
In [1]:
'''
for layer in model.layers:
print(f"Layer: {layer.name}")
weights = layer.get_weights() # Returns [weights, biases] or just [weights] depending on the layer
if weights: # Check if the layer has parameters
for param in weights:
print(param.shape)
print(param)
'''
Out[1]:
'\nfor layer in model.layers:\n print(f"Layer: {layer.name}")\n weights = layer.get_weights() # Returns [weights, biases] or just [weights] depending on the layer\n if weights: # Check if the layer has parameters\n for param in weights:\n print(param.shape)\n print(param)\n'
In [ ]:
import matplotlib.pyplot as plt
import numpy as np
# Get the weights of the first Conv2D layer
filters, biases = model.layers[0].get_weights()
print(filters.shape)
# Normalize filter values for visualization
#filters = (filters - filters.min()) / (filters.max() - filters.min())
# Plot the filters
num_filters = filters.shape[-1]
fig, axes = plt.subplots(1, num_filters, figsize=(20, 8))
print(filters[:,:,0,0])
for i in range(num_filters):
ax = axes[i]
print(filters[:,:,0,i])
img = ax.imshow(filters[:, :, 0, i], cmap='gray')
ax.axis('off')
img.set_clim(-1, 1) # Equivalent to caxis in MATLAB
plt.show()
(3, 3, 1, 16) [[ 0.21415356 -0.30885267 -0.6519661 ] [ 0.5058699 0.23093837 -0.22200817] [ 0.19406222 0.12560114 0.19133475]] [[ 0.21415356 -0.30885267 -0.6519661 ] [ 0.5058699 0.23093837 -0.22200817] [ 0.19406222 0.12560114 0.19133475]] [[ 0.13758168 0.2611158 0.13047461] [-0.10168032 0.20637156 0.26559454] [-0.54037744 -0.26272145 -0.0892069 ]] [[-0.45447803 0.110102 0.2370891 ] [ 0.01917345 0.47166994 0.04347578] [ 0.1570626 -0.07592573 -0.35444763]] [[-0.6938688 -0.05676343 0.5356932 ] [-0.33486983 0.20785178 0.28816774] [-0.20069587 0.09422254 0.07748269]] [[ 0.11412303 0.26057878 0.18961528] [-0.10704428 0.03975838 0.13112152] [-0.4502424 -0.19582744 -0.438199 ]] [[ 0.31722534 0.22499524 0.16056031] [ 0.05747228 0.25339037 0.17074552] [ 0.03227609 0.13687608 -0.1061388 ]] [[ 0.07825576 0.40836647 0.4523092 ] [-0.2057633 -0.08299793 0.26804474] [-0.7127716 -0.2987081 -0.1287441 ]] [[ 0.07901289 0.07470872 0.31638077] [ 0.25074646 0.2950283 0.03148688] [-0.28968665 -0.46267453 -0.4003041 ]] [[-0.21390766 -0.24693145 0.17037503] [-0.09921002 0.29982483 0.29925054] [-0.12932292 0.1117539 -0.14127398]] [[-0.09663841 0.0290889 0.08615615] [ 0.18088852 0.34550953 -0.2610065 ] [ 0.11386446 -0.11024614 -0.2258369 ]] [[-0.2561223 0.18832779 -0.0936925 ] [-0.23700483 0.3406391 -0.07570899] [-0.01622296 0.04902215 -0.03053573]] [[-0.31174532 0.28981948 0.12505637] [ 0.23953749 0.42738876 -0.22290403] [ 0.1021284 -0.08801013 -0.510321 ]] [[ 0.25381076 0.13187167 0.05188906] [-0.13400862 0.20843098 0.05804522] [-0.25477076 0.22373801 0.16677879]] [[ 0.3697697 0.32917467 0.28125772] [-0.3935351 -0.66763455 -0.60329956] [-0.16455817 0.15415668 0.18668981]] [[ 0.04671665 0.43674755 0.20692779] [ 0.22960134 0.14111868 -0.3492528 ] [-0.01214183 -0.18648607 -0.33370447]] [[-0.37765288 -0.30157796 0.47008973] [ 0.2407328 -0.44805565 0.13863577] [ 0.29043388 -0.00142932 -0.3981033 ]]
In [ ]:
# Visualize tht second layer
# Get the weights of the second Conv2D layer
filters, biases = model.layers[2].get_weights()
# Normalize filter values for visualization
#filters = (filters - filters.min()) / (filters.max() - filters.min())
print(filters.shape)
# Plot the filters
num_filters = filters.shape[-1]
print(num_filters)
fig, axes = plt.subplots(2, int(num_filters/2), figsize=(20, 3))
for i in range(num_filters):
#ax = axes[i]
ax = axes[i // int(np.ceil(num_filters / 2))][i % int(np.ceil(num_filters / 2))]
#print(filters[:,:,0,i])
img = ax.imshow(filters[:, :, 0, i], cmap='gray')
ax.axis('off')
img.set_clim(-1, 1) # Equivalent to caxis in MATLAB
plt.show()
fig, axes = plt.subplots(2, int(num_filters/2), figsize=(20, 3))
for i in range(num_filters):
#ax = axes[i]
ax = axes[i // int(np.ceil(num_filters / 2))][i % int(np.ceil(num_filters / 2))]
#print(filters[:,:,0,i])
img = ax.imshow(filters[:, :, 1, i], cmap='gray')
ax.axis('off')
img.set_clim(-1, 1) # Equivalent to caxis in MATLAB
plt.show()
(3, 3, 16, 32) 32
In [ ]:
import seaborn as sns
# Get weights of the first Dense layer
dense_weights, dense_biases = model.layers[-2].get_weights()
# Visualize as a heatmap
plt.figure(figsize=(8, 24))
sns.heatmap(dense_weights, cmap='coolwarm', cbar=True)
plt.title("Dense Layer Weights")
plt.xlabel("Neurons")
plt.ylabel("Input Features")
plt.show()
In [ ]:
# Get weights of the first Dense layer
dense_weights, dense_biases = model.layers[-1].get_weights()
# Visualize as a heatmap
plt.figure(figsize=(4, 6))
sns.heatmap(dense_weights, cmap='coolwarm', cbar=True)
plt.title("Dense Layer Weights")
plt.xlabel("Neurons")
plt.ylabel("Input Features")
plt.show()
In [ ]:
from tensorflow.keras.utils import plot_model
plot_model(model, to_file='CNN_MNIST_Model.png', show_shapes=True, show_layer_names=True)
Out[ ]:
In [ ]:
img = x_test_image[0,:,:]
Input = img.reshape(-1, 28, 28, 1)
output = model.predict(Input)
print(output.shape)
plt.imshow(img)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 120ms/step (1, 10)
Out[ ]:
<matplotlib.image.AxesImage at 0x7f1a520af550>
In [ ]:
from tensorflow.keras.models import Model
# Create a model that outputs the activations of the first Conv2D layer
layer_outputs = model.layers[0].output # Get the output of the first Conv2D layer
print(model.inputs)
activation_model = Model(inputs=model.inputs, outputs=layer_outputs)
[<KerasTensor shape=(None, 28, 28, 1), dtype=float32, sparse=False, name=keras_tensor>]
In [ ]:
# Use a sample image from your dataset (ensure it has the correct shape)
sample_image = np.expand_dims(x_test_image[0], axis=0) # Reshape to (1, 28, 28, 1)
# Pass the image through the model to get the activations
feature_maps = activation_model.predict(sample_image)
# Print the shape of the resulting feature maps
print("Feature maps shape:", feature_maps.shape) # Shape: (1, 26, 26, num_filters)
# Visualize the first feature map
fig, axes = plt.subplots(2,8, figsize=(20, 8))
num_filters =16
for i in range(num_filters):
ax = axes[i // int(np.ceil(num_filters / 2))][i % int(np.ceil(num_filters / 2))]
img = ax.imshow(feature_maps[0, :, :, i], cmap='coolwarm')
ax.axis('off')
img.set_clim(-1, 1)
plt.show()
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 59ms/step Feature maps shape: (1, 26, 26, 16)
In [ ]:
# Create a model that outputs the activations of the first Conv2D layer
layer_outputs = model.layers[2].output # Get the output of the first Conv2D layer
print(model.inputs)
activation_model = Model(inputs=model.inputs, outputs=layer_outputs)
[<KerasTensor shape=(None, 28, 28, 1), dtype=float32, sparse=False, name=keras_tensor>]
In [ ]:
# Use a sample image from your dataset (ensure it has the correct shape)
sample_image = np.expand_dims(x_test_image[0], axis=0) # Reshape to (1, 28, 28, 1)
# Pass the image through the model to get the activations
feature_maps = activation_model.predict(sample_image)
# Print the shape of the resulting feature maps
print("Feature maps shape:", feature_maps.shape) # Shape: (1, 26, 26, num_filters)
# Visualize the first feature map
num_filters =32
fig, axes = plt.subplots(2,int(num_filters/2), figsize=(20, 3))
for i in range(num_filters):
ax = axes[i // int(np.ceil(num_filters / 2))][i % int(np.ceil(num_filters / 2))]
img = ax.imshow(feature_maps[0, :, :, i], cmap='coolwarm')
ax.axis('off')
img.set_clim(-1, 1)
plt.show()
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 377ms/step Feature maps shape: (1, 11, 11, 32)