代码拉取完成,页面将自动刷新
# Checking your version of Python
import sys
print(sys.version)
3.11.9 | packaged by conda-forge | (main, Apr 19 2024, 18:27:10) [MSC v.1938 64 bit (AMD64)]
#import required libraries
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras import layers, models
from keras.models import Sequential
import os
# The original source of fake and real image is the OpenForensics++ Dataset
# available at https://zenodo.org/records/5528418#.YpdlS2hBzDd under the CC-BY 4.0 License.
# A subset of above dataset is available at Kaggle here:
#https://www.kaggle.com/code/diegoguizanlopez/it-s-an-ai-or-a-person/input
#The dataset used in this implementation is a subset of Kaggle dataset
# I have created this folder "shorter_df_images" to contain subset of images downloaded from Kaggle
# You can use entire dataset downloaded from Kaggle and save it using any name. Use the name of your folder
# as value of "imagedataset_path"
imagedataset_path = "shorter_df_images"
# Training images are in the subfolder called "Train"
train_dir = os.path.join(imagedataset_path,"Train")
# Test images are in the subfolder called "Test"
test_dir = os.path.join(imagedataset_path,"Test")
# Validation images are in the subfolder called "Validation"
val_dir = os.path.join(imagedataset_path,"Validation")
#Loading Images
#Number of images in one batch
batch_size = 32
#image height and width
img_height = 128
img_width = 128
#Create a tensor of training images present in the train_dir
train_ds = tf.keras.utils.image_dataset_from_directory(
train_dir,
labels='inferred',
color_mode="rgb",
seed=42,
batch_size=batch_size,
image_size=(img_height, img_width))
#Create a tensor of test images present in the test_dir
test_ds = tf.keras.utils.image_dataset_from_directory(
test_dir,
labels='inferred',
color_mode="rgb",
seed=42,
batch_size=batch_size,
image_size=(img_height, img_width))
#Create a tensor of validation images present in the val_dir
validation_ds = tf.keras.utils.image_dataset_from_directory(
val_dir,
labels='inferred',
color_mode="rgb",
seed=42,
batch_size=batch_size,
image_size=(img_height, img_width))
Found 7934 files belonging to 2 classes. Found 7397 files belonging to 2 classes. Found 7934 files belonging to 2 classes.
# Print the unique class labels from images. This comes from the unique folder names
#within Train, Test and Validation folders.
class_names = train_ds.class_names
print(class_names)
['Fake', 'Real']
# DisplayPlot first 9 images from training dataset using matplotlib.pyplot
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
for images, labels in train_ds.take(1):
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
#print the batch size and shape of each image in a batch of training data
for image_batch, labels_batch in train_ds:
print(image_batch.shape)
#print the number of labels in each batch
print(labels_batch.shape)
break
(32, 128, 128, 3) (32,)
# let us not define a deep CNN model for image feature extraction and classification
img_width = 128
img_height = 128
#Input() defines the input layer of the CNN
#Its shape argument specified image width, height and number of channels.
inputs = Input(shape = (img_width, img_height, 3))
# Sequential() initializes a sequential deep model.
model = models.Sequential()
# add the input layer to the model
model.add(inputs)
#add first convolutional block with two convolutional layers, and a MaxPooling2D layer.
model.add(Conv2D(32,(3,3),activation="relu", padding='same'))
model.add(Conv2D(32,(3,3),activation="relu", padding='same'))
model.add(MaxPooling2D((2,2), strides=(2, 2)))
#add second convolutional block with two convolutional layers, and a MaxPooling2D layer.
model.add(Conv2D(64,(3,3),activation="relu", padding='same'))
model.add(Conv2D(64,(3,3),activation="relu", padding='same'))
model.add(MaxPooling2D((2,2), strides=(2, 2)))
#add third convolutional block with two convolutional layers, and a MaxPooling2D layer.
model.add(Conv2D(128,(3,3),activation="relu", padding='same'))
model.add(Conv2D(128,(3,3),activation="relu", padding='same'))
model.add(MaxPooling2D((2,2), strides=(2, 2)))
#add 4th convolutional block with two convolutional layers, and a MaxPooling2D layer.
model.add(Conv2D(128,(3,3),activation="relu", padding='same'))
model.add(Conv2D(128,(3,3),activation="relu", padding='same'))
model.add(MaxPooling2D((2,2), strides=(2, 2)))
#add 5th convolutional block with two convolutional layers, and a MaxPooling2D layer.
model.add(Conv2D(128,(3,3),activation="relu", padding='same'))
model.add(Conv2D(128,(3,3),activation="relu", padding='same'))
model.add(MaxPooling2D((2,2), strides=(2, 2)))
#add a Flatten() layer to convert extracted features into a row vector.
model.add(Flatten())
#add a dropout layer to reduce overfitting.
model.add(Dropout(0.5))
#add two fully connected layers with 128 and 256 neurons respectively
model.add(Dense(128,activation="relu"))
model.add(Dense(256,activation="relu"))
#add a final layer with a single neuron
#this layer gives the final classification label of the test image
model.add(Dense(1,activation="sigmoid"))
#print the model structure summary
model.summary()
Model: "sequential_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ │ conv2d_10 (Conv2D) │ (None, 128, 128, 32) │ 896 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_11 (Conv2D) │ (None, 128, 128, 32) │ 9,248 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_5 (MaxPooling2D) │ (None, 64, 64, 32) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_12 (Conv2D) │ (None, 64, 64, 64) │ 18,496 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_13 (Conv2D) │ (None, 64, 64, 64) │ 36,928 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_6 (MaxPooling2D) │ (None, 32, 32, 64) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_14 (Conv2D) │ (None, 32, 32, 128) │ 73,856 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_15 (Conv2D) │ (None, 32, 32, 128) │ 147,584 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_7 (MaxPooling2D) │ (None, 16, 16, 128) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_16 (Conv2D) │ (None, 16, 16, 128) │ 147,584 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_17 (Conv2D) │ (None, 16, 16, 128) │ 147,584 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_8 (MaxPooling2D) │ (None, 8, 8, 128) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_18 (Conv2D) │ (None, 8, 8, 128) │ 147,584 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_19 (Conv2D) │ (None, 8, 8, 128) │ 147,584 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_9 (MaxPooling2D) │ (None, 4, 4, 128) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ flatten_1 (Flatten) │ (None, 2048) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout_1 (Dropout) │ (None, 2048) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_3 (Dense) │ (None, 128) │ 262,272 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_4 (Dense) │ (None, 256) │ 33,024 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_5 (Dense) │ (None, 1) │ 257 │ └──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 1,172,897 (4.47 MB)
Trainable params: 1,172,897 (4.47 MB)
Non-trainable params: 0 (0.00 B)
#compile the model defined above
#we are using 'adam' as the optimizer, BinaryCrossEntropy() loss as the loss function
#since this is a two class classification
# problem and accuracy is the evaluation metric.
model.compile('adam',loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy'])
#Let us train the model for 25 epochs
epochs = 25
history = model.fit(train_ds,epochs=epochs,batch_size=32,validation_data=validation_ds)
Epoch 1/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m105s[0m 416ms/step - accuracy: 0.6602 - loss: 0.6226 - val_accuracy: 0.6927 - val_loss: 0.6284 Epoch 2/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 412ms/step - accuracy: 0.9059 - loss: 0.2594 - val_accuracy: 0.6852 - val_loss: 0.9248 Epoch 3/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 413ms/step - accuracy: 0.9230 - loss: 0.2151 - val_accuracy: 0.6398 - val_loss: 0.7521 Epoch 4/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 413ms/step - accuracy: 0.9293 - loss: 0.1982 - val_accuracy: 0.6910 - val_loss: 0.6695 Epoch 5/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m101s[0m 409ms/step - accuracy: 0.9321 - loss: 0.1897 - val_accuracy: 0.6841 - val_loss: 0.6271 Epoch 6/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m101s[0m 409ms/step - accuracy: 0.9395 - loss: 0.1750 - val_accuracy: 0.6833 - val_loss: 0.7350 Epoch 7/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m103s[0m 415ms/step - accuracy: 0.9394 - loss: 0.1654 - val_accuracy: 0.7048 - val_loss: 0.6382 Epoch 8/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m101s[0m 410ms/step - accuracy: 0.9446 - loss: 0.1486 - val_accuracy: 0.7027 - val_loss: 0.5972 Epoch 9/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m104s[0m 422ms/step - accuracy: 0.9485 - loss: 0.1434 - val_accuracy: 0.7177 - val_loss: 0.6644 Epoch 10/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m98s[0m 397ms/step - accuracy: 0.9535 - loss: 0.1286 - val_accuracy: 0.6858 - val_loss: 0.7297 Epoch 11/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m100s[0m 401ms/step - accuracy: 0.9562 - loss: 0.1227 - val_accuracy: 0.7226 - val_loss: 0.6804 Epoch 12/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 413ms/step - accuracy: 0.9538 - loss: 0.1241 - val_accuracy: 0.7153 - val_loss: 0.8201 Epoch 13/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 412ms/step - accuracy: 0.9561 - loss: 0.1104 - val_accuracy: 0.7130 - val_loss: 0.7139 Epoch 14/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m101s[0m 409ms/step - accuracy: 0.9597 - loss: 0.0939 - val_accuracy: 0.7254 - val_loss: 0.7403 Epoch 15/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m103s[0m 417ms/step - accuracy: 0.9675 - loss: 0.0931 - val_accuracy: 0.7082 - val_loss: 0.7179 Epoch 16/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 411ms/step - accuracy: 0.9608 - loss: 0.0955 - val_accuracy: 0.7348 - val_loss: 0.6936 Epoch 17/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m101s[0m 406ms/step - accuracy: 0.9677 - loss: 0.0817 - val_accuracy: 0.7256 - val_loss: 0.9103 Epoch 18/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m101s[0m 409ms/step - accuracy: 0.9699 - loss: 0.0809 - val_accuracy: 0.6962 - val_loss: 0.9583 Epoch 19/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 411ms/step - accuracy: 0.9714 - loss: 0.0724 - val_accuracy: 0.7182 - val_loss: 1.2235 Epoch 20/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 412ms/step - accuracy: 0.9745 - loss: 0.0634 - val_accuracy: 0.7533 - val_loss: 0.8459 Epoch 21/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m102s[0m 410ms/step - accuracy: 0.9789 - loss: 0.0555 - val_accuracy: 0.7656 - val_loss: 0.8919 Epoch 22/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m100s[0m 405ms/step - accuracy: 0.9793 - loss: 0.0548 - val_accuracy: 0.7222 - val_loss: 1.0960 Epoch 23/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m99s[0m 401ms/step - accuracy: 0.9765 - loss: 0.0607 - val_accuracy: 0.7454 - val_loss: 1.5184 Epoch 24/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m100s[0m 404ms/step - accuracy: 0.9820 - loss: 0.0439 - val_accuracy: 0.7281 - val_loss: 1.6889 Epoch 25/25 [1m248/248[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m106s[0m 428ms/step - accuracy: 0.9844 - loss: 0.0451 - val_accuracy: 0.7478 - val_loss: 1.0688
# plot training accuracy, validation accuracy, training loss and validation loss over 25 epochs
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = 25
epochs_range = range(epochs)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
#Evaluate the trained model on test data
model.evaluate(test_ds)
[1m232/232[0m [32m━━━━━━━━━━━━━━━━━━━━[0m[37m[0m [1m20s[0m 87ms/step - accuracy: 0.7227 - loss: 1.1331
[1.0992017984390259, 0.7317831516265869]
#Save the trained model to your hard drive
model.save("deepfake_imagedetector_shorterdataset.keras")
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。