Image Classification
Keras
litav commited on
Commit
0f1701c
·
verified ·
1 Parent(s): b7f4857

Upload 9 files

Browse files

Classic CNN model

.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ best_model_weights/model_fold_1.best.weights.h5.keras filter=lfs diff=lfs merge=lfs -text
37
+ best_model_weights/model_fold_2.best.weights.h5.keras filter=lfs diff=lfs merge=lfs -text
38
+ best_model_weights/model_fold_3.best.weights.h5.keras filter=lfs diff=lfs merge=lfs -text
39
+ best_model_weights/model_fold_4.best.weights.h5.keras filter=lfs diff=lfs merge=lfs -text
best_model_weights/model_fold_1.best.weights.h5.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:65d47255dfa6fd93f3d72147528936db370bbdf9f8dc226baf4b1e1c5eeef46a
3
+ size 39251509
best_model_weights/model_fold_2.best.weights.h5.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8bd913d026ad213719c7cc8c2cf3a2c11a6c623e915c1df2bd6044e55b372ae0
3
+ size 39251523
best_model_weights/model_fold_3.best.weights.h5.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a2cf05d5dc6c89f0d06eb54d1fc892a375e07872d3ed528decc9bc9a819ae250
3
+ size 39251523
best_model_weights/model_fold_4.best.weights.h5.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:74103dccb845a497eca6ac404336786e559dc6c80df9cd795d6e361fc23da573
3
+ size 39251525
cnn_SaveInPainting.py ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Sat May 18 16:15:32 2024
4
+ @author: litav
5
+ """
6
+
7
+ # -*- coding: utf-8 -*-
8
+ """
9
+ Created on Sat May 18 16:15:32 2024
10
+ @author: litav
11
+ """
12
+
13
+
14
+ #dropout 0.5
15
+ # Set parameters for cross-validation
16
+ #kf = KFold(n_splits=4, shuffle=True, random_state=42)
17
+ #batch_size = 64
18
+ #epochs = 15
19
+ #Average accuracy across all folds: 78.56%
20
+ #Test Loss: 0.49228477478027344, Test Accuracy: 0.7706093192100525
21
+ #Classification Summary:
22
+ #Real images correctly classified: 107
23
+ #Real images incorrectly classified: 32
24
+ #Fake images correctly classified: 108
25
+ #Fake images incorrectly classified: 32
26
+ #Classification Report:
27
+ # precision recall f1-score support
28
+ #
29
+ # Real 0.77 0.77 0.77 139
30
+ # Fake 0.77 0.77 0.77 140
31
+
32
+
33
+
34
+ import numpy as np
35
+ import tensorflow as tf
36
+ import random
37
+ import os
38
+ import pandas as pd
39
+ import cv2
40
+ import matplotlib.pyplot as plt
41
+ from sklearn.model_selection import KFold
42
+ from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, Flatten
43
+ from tensorflow.keras.optimizers import Adam
44
+ from tensorflow.keras.models import Sequential
45
+ from sklearn.metrics import accuracy_score, confusion_matrix, ConfusionMatrixDisplay
46
+ from tensorflow.keras.layers import Dropout
47
+ from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
48
+ from sklearn.metrics import precision_score, recall_score, f1_score, classification_report
49
+
50
+
51
+ # Suppress iCCP warning
52
+ import warnings
53
+ warnings.filterwarnings("ignore", category=UserWarning, message=".*iCCP:.*")
54
+
55
+ # Define data paths
56
+ train_real_folder = 'datasets/training_set/real/'
57
+ train_fake_folder = 'datasets/training_set/fake/'
58
+ test_real_folder = 'datasets/test_set/real/'
59
+ test_fake_folder = 'datasets/test_set/fake/'
60
+
61
+ # Load train image paths and labels
62
+ train_image_paths = []
63
+ train_labels = []
64
+
65
+ # Load train_real image paths and labels
66
+ for filename in os.listdir(train_real_folder):
67
+ image_path = os.path.join(train_real_folder, filename)
68
+ label = 0 # Real images have label 0
69
+ train_image_paths.append(image_path)
70
+ train_labels.append(label)
71
+
72
+ # Load train_fake image paths and labels
73
+ for filename in os.listdir(train_fake_folder):
74
+ image_path = os.path.join(train_fake_folder, filename)
75
+ label = 1 # Fake images have label 1
76
+ train_image_paths.append(image_path)
77
+ train_labels.append(label)
78
+
79
+ # Load test image paths and labels
80
+ test_image_paths = []
81
+ test_labels = []
82
+
83
+ # Load test_real image paths and labels
84
+ for filename in os.listdir(test_real_folder):
85
+ image_path = os.path.join(test_real_folder, filename)
86
+ label = 0 # Assuming test real images are all real (label 0)
87
+ test_image_paths.append(image_path)
88
+ test_labels.append(label)
89
+
90
+ # Load test_fake image paths and labels
91
+ for filename in os.listdir(test_fake_folder):
92
+ image_path = os.path.join(test_fake_folder, filename)
93
+ label = 1 # Assuming test fake images are all fake (label 1)
94
+ test_image_paths.append(image_path)
95
+ test_labels.append(label)
96
+
97
+ # Create DataFrames
98
+ train_dataset = pd.DataFrame({'image_path': train_image_paths, 'label': train_labels})
99
+ test_dataset = pd.DataFrame({'image_path': test_image_paths, 'label': test_labels})
100
+
101
+ # Function to preprocess images
102
+ def preprocess_image(image_path):
103
+ """Loads, resizes, and normalizes an image."""
104
+ image = cv2.imread(image_path)
105
+ resized_image = cv2.resize(image, (128, 128)) # Target size defined here
106
+ normalized_image = resized_image.astype(np.float32) / 255.0
107
+ return normalized_image
108
+
109
+ # Preprocess all images and convert labels to numpy arrays
110
+ X = np.array([preprocess_image(path) for path in train_image_paths])
111
+ Y = np.array(train_labels)
112
+
113
+ # Define discriminator network
114
+ def build_discriminator(input_shape, dropout_rate=0.5):
115
+ model = Sequential()
116
+ model.add(Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
117
+ model.add(MaxPooling2D((2, 2)))
118
+ model.add(Conv2D(64, (3, 3), activation='relu'))
119
+ model.add(MaxPooling2D((2, 2)))
120
+ model.add(Conv2D(64, (3, 3), activation='relu'))
121
+ model.add(Flatten())
122
+ model.add(Dense(64, activation='relu'))
123
+ model.add(Dropout(dropout_rate)) # Adding dropout layer
124
+ model.add(Dense(1, activation='sigmoid'))
125
+ return model
126
+
127
+ # Function to check if previous weights exist
128
+ def load_previous_weights(model, fold_number):
129
+ weights_file = f'model_weights/model_fold_{fold_number}.weights.h5'
130
+ if os.path.exists(weights_file):
131
+ model.load_weights(weights_file)
132
+ print(f"Loaded weights from {weights_file}")
133
+ else:
134
+ print("No previous weights found.")
135
+
136
+ # Function to save weights if current accuracy is higher
137
+ def save_updated_weights(model, fold_number, val_accuracy, best_accuracy):
138
+ weights_file = f'model_weights/model_fold_{fold_number}.weights.h5'
139
+ if val_accuracy > best_accuracy:
140
+ model.save_weights(weights_file)
141
+ print(f"Saved updated weights to {weights_file} with val_accuracy: {val_accuracy:.4f}")
142
+ return val_accuracy
143
+ else:
144
+ print(f"Did not save weights for fold {fold_number} as val_accuracy {val_accuracy:.4f} is not better than {best_accuracy:.4f}")
145
+ return best_accuracy
146
+
147
+ # Set parameters for cross-validation
148
+ kf = KFold(n_splits=4, shuffle=True, random_state=42)
149
+ batch_size = 32
150
+ epochs = 15
151
+
152
+ # Lists to store accuracy and loss for each fold
153
+ accuracy_per_fold = []
154
+ loss_per_fold = []
155
+ # Store the best accuracies for each fold
156
+ best_accuracies = [0] * kf.get_n_splits()
157
+
158
+
159
+ # Perform K-Fold Cross-Validation
160
+ for fold_number, (train_index, val_index) in enumerate(kf.split(X), 1):
161
+ X_train, X_val = X[train_index], X[val_index]
162
+ Y_train, Y_val = Y[train_index], Y[val_index]
163
+
164
+ # Create and compile model
165
+ input_dim = X_train.shape[1:] # Dimensionality of the input images
166
+ model = build_discriminator(input_dim)
167
+ model.compile(loss='binary_crossentropy', optimizer=Adam(0.0002, 0.5), metrics=['accuracy'])
168
+
169
+ # Load previous weights if they exist
170
+ load_previous_weights(model, fold_number)
171
+
172
+ # Define Early Stopping callback
173
+ early_stopping = EarlyStopping(monitor='val_accuracy', patience=5, restore_best_weights=True)
174
+
175
+ # Define ModelCheckpoint callback to save the best weights
176
+ checkpoint = ModelCheckpoint(filepath=f'best_model_weights/model_fold_{fold_number}.best.weights.h5.keras', monitor='val_accuracy', save_best_only=True, mode='max')
177
+
178
+ # Train the model with the callbacks
179
+ history = model.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size, verbose=2,
180
+ validation_data=(X_val, Y_val), callbacks=[early_stopping, checkpoint])
181
+
182
+ # Store the accuracy and loss for this folds
183
+ average_val_accuracy = np.mean(history.history['val_accuracy'])
184
+ accuracy_per_fold.append(average_val_accuracy)
185
+ average_val_loss = np.mean(history.history['val_loss'])
186
+ loss_per_fold.append(average_val_loss)
187
+
188
+ # Save updated weights if accuracy is high
189
+ best_accuracies[fold_number - 1] = save_updated_weights(model, fold_number, average_val_accuracy, best_accuracies[fold_number - 1])
190
+
191
+
192
+ # Print fold accuracy
193
+ print(f'Fold {fold_number} average accuracy: {average_val_accuracy*100:.2f}%')
194
+
195
+ # Print average accuracy across all folds
196
+ print(f'Average accuracy across all folds: {np.mean(accuracy_per_fold)*100:.2f}%')
197
+
198
+ # Load the model weights of the best model
199
+ best_model_index = np.argmax(accuracy_per_fold)
200
+ best_model_path = f'best_model_weights/model_fold_{best_model_index + 1}.best.weights.h5.keras'
201
+ model.load_weights(best_model_path)
202
+
203
+ # Evaluate the preprocessed test images using the best model
204
+ test_loss, test_accuracy = model.evaluate(np.array([preprocess_image(path) for path in test_image_paths]), np.array(test_labels))
205
+ print(f"\nTest Loss: {test_loss}, Test Accuracy: {test_accuracy}")
206
+
207
+ # Predict labels for the test set using the best model
208
+ predictions = model.predict(np.array([preprocess_image(path) for path in test_image_paths]))
209
+ predicted_labels = (predictions > 0.5).astype(int).flatten()
210
+
211
+ # Summarize the classification results
212
+ true_real_correct = np.sum((np.array(test_labels) == 0) & (predicted_labels == 0))
213
+ true_real_incorrect = np.sum((np.array(test_labels) == 0) & (predicted_labels == 1))
214
+ true_fake_correct = np.sum((np.array(test_labels) == 1) & (predicted_labels == 1))
215
+ true_fake_incorrect = np.sum((np.array(test_labels) == 1) & (predicted_labels == 0))
216
+
217
+ print("\nClassification Summary:")
218
+ print(f"Real images correctly classified: {true_real_correct}")
219
+ print(f"Real images incorrectly classified: {true_real_incorrect}")
220
+ print(f"Fake images correctly classified: {true_fake_correct}")
221
+ print(f"Fake images incorrectly classified: {true_fake_incorrect}")
222
+
223
+
224
+ # Print detailed classification report
225
+ print("\nClassification Report:")
226
+ print(classification_report(test_labels, predicted_labels, target_names=['Real', 'Fake']))
227
+
228
+ print(model.summary())
229
+
230
+
231
+ # Plot confusion matrix
232
+ cm = confusion_matrix(test_labels, predicted_labels)
233
+ disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=['Real', 'Fake'])
234
+ disp.plot(cmap=plt.cm.Blues)
235
+ plt.title("Confusion Matrix")
236
+ plt.show()
237
+
238
+ # Plot training & validation accuracy values
239
+ plt.figure(figsize=(12, 4))
240
+ plt.subplot(1, 2, 1)
241
+ plt.plot(history.history['accuracy'])
242
+ plt.plot(history.history['val_accuracy'])
243
+ plt.title('Model accuracy')
244
+ plt.ylabel('Accuracy')
245
+ plt.xlabel('Epoch')
246
+ plt.legend(['Train', 'Validation'], loc='upper left')
247
+ plt.xticks(np.arange(0, len(history.history['accuracy']), step=1), np.arange(1, len(history.history['accuracy']) + 1, step=1))
248
+
249
+
250
+ # Plot training & validation loss values
251
+ plt.subplot(1, 2, 2)
252
+ plt.plot(history.history['loss'])
253
+ plt.plot(history.history['val_loss'])
254
+ plt.title('Model loss')
255
+ plt.ylabel('Loss')
256
+ plt.xlabel('Epoch')
257
+ plt.legend(['Train', 'Validation'], loc='upper left')
258
+ plt.xticks(np.arange(0, len(history.history['loss']), step=1), np.arange(1, len(history.history['loss']) + 1, step=1))
259
+
260
+
261
+ plt.tight_layout()
262
+ plt.show()
263
+
264
+ # Plot validation accuracy and loss per fold
265
+ plt.figure(figsize=(12, 4))
266
+ plt.subplot(1, 2, 1)
267
+ plt.plot(range(1, kf.get_n_splits() + 1), accuracy_per_fold, marker='o')
268
+ plt.title('Validation Accuracy per Fold')
269
+ plt.xlabel('Fold')
270
+ plt.ylabel('Accuracy')
271
+
272
+ plt.subplot(1, 2, 2)
273
+ plt.plot(range(1, kf.get_n_splits() + 1), loss_per_fold, marker='o')
274
+ plt.title('Validation Loss per Fold')
275
+ plt.xlabel('Fold')
276
+ plt.ylabel('Loss')
277
+
278
+ plt.tight_layout()
279
+ plt
280
+
281
+
model_weights/model_fold_1.weights.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d2cb3882c31504ab9bda68577c07b613fac073019255d3ad929b44866ab1311d
3
+ size 39246536
model_weights/model_fold_2.weights.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ff9663a3af3a497aa8f4a101e0d688c8e8f6370702ff92d12e89d612eb611e95
3
+ size 39246536
model_weights/model_fold_3.weights.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0b2e232ae7da197a68e515b0f0a0c743aa7624b4258bc31d8c1e7a194ceddda1
3
+ size 39246536
model_weights/model_fold_4.weights.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7ebe3373affd9cc9d61b172deb237b5dbaf3a65e833962266fbc11549c68d48d
3
+ size 39246536