记录

这是课堂上做的一个关于图像篡改识别的题目,因为前后花的时间比较多,虽然最后实现的效果也不怎么行,但是这个过程踩了很多坑,这里记录一下。

文章目录

  • 记录
  • 前提
  • 题目分析
  • 网络搭建
    • 依赖包
    • 数据读取处理
    • 网络搭建
    • 训练参数
    • 预测函数
    • 模型保存
  • 完整源码
    • 训练以及预测的完整源码:
    • 预测的分模块源码

前提

  • 必要的GPU训练环境
  • 基础的神经网络知识
  • 这里用的环境:
    tensorflow2.8
    python3.9

题目分析

这个题目就是一个给定的数据集,里面包含训练集和测试集,需要通过训练让算法能够识别出来一张照片是否被篡改,可以上知乎搜索一下与数字图像篡改有关的文章,一般来说用传统的算法都比较难分辨,而网上也比较少统计现成的算法,而神经网络是比较常用的方式,所以就自己学着搭了一个九层的卷积神经网络,最后的识别效果相比于其他使用Resnet18等一些常规的网络差别不是很大,这个很大程度也只是因为数据集太小了。
这里提供数据集:链接:

https://pan.baidu.com/s/1g1BMMklZnU_wiUWB0Jne0Q

提取码:ddxz
–来自百度网盘超级会员V3的分享
下面是训练集里面一些的图片,
fake:

real:

数据集只有一千多张照片,而要在一千多张照片里面去训练出一个比较好的网络模型是比较难的,而这份代码最后实现的效果也只是65%左右的识别正确率,而我们通过人工测试得到的参考准确率大约为75%。
这里面话可以给大家推荐一个其他的真假人脸的数据集,下面这个数据集有14万的照片:

https://www.kaggle.com/xhlulu/140k-real-and-fake-faces

但是要注意这两个数据的特征不一样,也就是说在用第二个数据来训练在第一个数据集的测试集是没有办法正确预测的(最起码在我这个模型里面是这样)。

网络搭建

用到的网络层:卷积层、池化层、平直层、全连接层
这些基本的概念大家可以自行学习,因为我的这份代码是用的TensorFlow框架搭建的,建议没基础的同学可以去参考这个从零搭建神经网络:

https://blog.csdn.net/weixin_44127327/article/details/121795916

依赖包

from keras.models import Sequential
from keras.layers import Conv2D, Flatten, Dense,MaxPool2D
import numpy as np
from keras.preprocessing import image
from keras.callbacks import EarlyStopping, ModelCheckpoint
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import ostry:from tensorflow.python.util import module_wrapper as deprecation
except ImportError:from tensorflow.python.util import deprecation_wrapper as deprecation
deprecation._PER_MODULE_WARNING_LIMIT = 0

数据读取处理

#定义batchsize
nbatch = 128
train_datagen = ImageDataGenerator(#数据集生成器,这里做了数据增强rescale=1./255,rotation_range=10.,width_shift_range=0.1,height_shift_range=0.1,zoom_range=0.2,horizontal_flip=True)test_datagen = ImageDataGenerator(rescale = 1./255)training_set = train_datagen.flow_from_directory('dataset/real_and_fake_face_training',#训练集路径target_size=(128,128),batch_size =nbatch,class_mode = 'binary')test_set = test_datagen.flow_from_directory('dataset/real_and_fake_face_validation',#验证集路径target_size=(128,128),batch_size =nbatch,class_mode = 'binary')

网络搭建

这里面就是卷积池化、卷积池化,这里并没有用上什么技巧性的东西

model = Sequential()model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=(128,128,3)))
#output (128-3)/1+1=126
model.add(MaxPool2D(pool_size=(2,2)))#这里的步长默认为池化核尺寸
#outpu (126-2)/2+1=63
model.add(Conv2D(64, kernel_size=(3, 3),activation='relu'))
#output=(63-3)/1+1=61
model.add(MaxPool2D(pool_size=(2,2)))
#output=(61-2)/2+1=30
model.add(Conv2D(128, kernel_size=(3, 3),activation='relu'))
#output=(30-3)+1=28
model.add(MaxPool2D(pool_size=(2,2)))
#output=(28-2)/2+1=14
model.add(Flatten())
#output=14*14*128=25088
model.add(Dense(activation="relu",units=256))model.add(Dense(activation="sigmoid",units=1))model.summary()         #输出网络结构

训练参数

model.compile(optimizer = 'adam',loss = 'binary_crossentropy',metrics = ['accuracy'])callbacks_list = [EarlyStopping(monitor='val_loss', patience=5),#model.save('.\\static_model\\static_my_model_test.h5'),ModelCheckpoint(filepath='.\\static_model\\my_model.hdf5', monitor='val_loss', save_best_only=True, mode ='max'),]history = model.fit_generator(training_set,steps_per_epoch=12, #这里面需要注意这个 这个是每个epoch的分步操作,最好能够设置为训练集总数/batchsizeepochs=10,validation_data=test_set,validation_steps=4, #这个同理,但是这个是对验证集的总数来说callbacks = callbacks_list #设置断电回调函数)

预测函数

这里的预测函数,可以根据需要自行调整,重点是需要使用model.predict(test_image)

def ImagePrediction(loc):testlen=len(os.listdir(loc))print("len(os.listdir(loc))=",len(os.listdir(loc)))pre_array=np.zeros(testlen)labels_array=np.loadtxt(",\\dataset\\label.txt",usecols=0)human_labels_array = np.loadtxt(".\\dataset\\human_label.txt", usecols=0)#print("labels_array=",labels_array)for i in range(1,len(os.listdir(loc))+1):path=loc+"\\img{}.jpg".format(i)#print("path=",path)test_image = image.load_img(path, target_size = (128,128))#plt.axis('off')#plt.imshow(test_image)test_image = image.img_to_array(test_image)test_image = np.expand_dims(test_image, axis =0)result = model.predict(test_image)if result[0][0] == 1:predictions = 'Real'pre_array[i-1]=1else:predictions = 'Fake'pre_array[i - 1] =-1#print('Prediction: ',predictions)print("第{}幅图:{}".format(i,predictions))#print("pre_array=",pre_array)turenum=0human_truenum=0for i in range(testlen):if pre_array[i]==labels_array[i]:turenum+=1if human_labels_array[i]==labels_array[i]:human_truenum+=1accuracy=turenum/testlen##Ref_accuarcy=human_truenum/testlenprint("Ref_accuarcy=",Ref_accuarcy,"accuracy=",accuracy)

模型保存

这里面的代码是直接把训练和预测放一起了,但是最好把两个分开,每次训练完把模型保存下来,方便下次的测试使用,而不用每次都重新训练。
模型保存的函数:

model.save('.\\static_model\\static_my_model.h5')

需要使用就加载:

model = load_model('.\\static_model\\static_my_model.h5')

完整源码

训练以及预测的完整源码:

from keras.models import Sequential
from keras.layers import Conv2D, Flatten, Dense,MaxPool2D
import numpy as np
from keras.preprocessing import image
from keras.callbacks import EarlyStopping, ModelCheckpoint
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import ostry:from tensorflow.python.util import module_wrapper as deprecation
except ImportError:from tensorflow.python.util import deprecation_wrapper as deprecation
deprecation._PER_MODULE_WARNING_LIMIT = 0#定义batchsize
nbatch = 128
train_datagen = ImageDataGenerator(rescale=1./255,#rotation_range=10.,#width_shift_range=0.1,#height_shift_range=0.1,#zoom_range=0.2,#horizontal_flip=True)test_datagen = ImageDataGenerator(rescale = 1./255)training_set = train_datagen.flow_from_directory('dataset/teach_train',target_size=(128,128),batch_size =nbatch,class_mode = 'binary')test_set = test_datagen.flow_from_directory('dataset/github_val',target_size=(128,128),batch_size =nbatch,class_mode = 'binary')h1 = plt.hist(training_set.classes, bins=range(0,3), alpha=0.8, color='blue', edgecolor='black')
h2 = plt.hist(test_set.classes,  bins=range(0,3), alpha=0.8, color='red', edgecolor='black')
plt.ylabel('# of instances')
plt.xlabel('Class')
plt.show()
"""for X, y in training_set:print(X.shape, y.shape)plt.figure(figsize=(16,16))for i in range(16):plt.subplot(4,4,i+1)plt.axis('off')plt.title('Label: ')img = np.uint8(255*X[i,:,:,0])plt.imshow(img, cmap='gray')break
plt.show()"""model = Sequential()model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=(128,128,3)))
#output (128-3)/1+1=126
model.add(MaxPool2D(pool_size=(2,2)))#这里的步长默认为池化核尺寸
#outpu (126-2)/2+1=63
model.add(Conv2D(64, kernel_size=(3, 3),activation='relu'))
#output=(63-3)/1+1=61
model.add(MaxPool2D(pool_size=(2,2)))
#output=(61-2)/2+1=30
model.add(Conv2D(128, kernel_size=(3, 3),activation='relu'))
#output=(30-3)+1=28
model.add(MaxPool2D(pool_size=(2,2)))
#output=(28-2)/2+1=14
model.add(Flatten())
#output=14*14*128=25088
model.add(Dense(activation="relu",units=256))model.add(Dense(activation="sigmoid",units=1))model.summary()model.compile(optimizer = 'adam',loss = 'binary_crossentropy',metrics = ['accuracy'])callbacks_list = [EarlyStopping(monitor='val_loss', patience=5),#model.save('.\\static_model\\static_my_model_test.h5'),ModelCheckpoint(filepath='.\\static_model\\my_model.hdf5', monitor='val_loss', save_best_only=True, mode ='max'),]history = model.fit_generator(training_set,steps_per_epoch=12, #这里面需要注意这个 这个是每个epoch的分步操作,最好能够设置为训练集总数/batchsizeepochs=10,validation_data=test_set,validation_steps=4, #这个同理,但是这个是对验证集的总数来说callbacks = callbacks_list #设置断电回调函数)print(training_set.class_indices)def ImagePrediction(loc):testlen=len(os.listdir(loc))print("len(os.listdir(loc))=",len(os.listdir(loc)))pre_array=np.zeros(testlen)labels_array=np.loadtxt(",\\dataset\\label.txt",usecols=0)human_labels_array = np.loadtxt(".\\dataset\\human_label.txt", usecols=0)#print("labels_array=",labels_array)for i in range(1,len(os.listdir(loc))+1):path=loc+"\\img{}.jpg".format(i)#print("path=",path)test_image = image.load_img(path, target_size = (128,128))#plt.axis('off')#plt.imshow(test_image)test_image = image.img_to_array(test_image)test_image = np.expand_dims(test_image, axis =0)result = model.predict(test_image)if result[0][0] == 1:predictions = 'Real'pre_array[i-1]=1else:predictions = 'Fake'pre_array[i - 1] =-1#print('Prediction: ',predictions)print("第{}幅图:{}".format(i,predictions))#print("pre_array=",pre_array)turenum=0human_truenum=0for i in range(testlen):if pre_array[i]==labels_array[i]:turenum+=1if human_labels_array[i]==labels_array[i]:human_truenum+=1accuracy=turenum/testlen##Ref_accuarcy=human_truenum/testlenprint("Ref_accuarcy=",Ref_accuarcy,"accuracy=",accuracy)#下面填写图片路径进行测试
img =".\\dataset\\real_and_fake_face_testing\\real_and_fake_face_testing"
test_image_1 = ImagePrediction(img)plt.figure(figsize=(16,6))
plt.subplot(1,2,1)
nepochs=len(history.history['loss'])
plt.plot(range(nepochs), history.history['loss'],     'r-', label='train')
plt.plot(range(nepochs), history.history['val_loss'], 'b-', label='val')
plt.legend(prop={'size': 20})
plt.ylabel('loss')
plt.xlabel('# of epochs')
plt.subplot(1,2,2)
plt.plot(range(nepochs), history.history['accuracy'],     'r-', label='train')
plt.plot(range(nepochs), history.history['val_accuracy'], 'b-', label='val')
plt.legend(prop={'size': 20})
plt.ylabel('accuracy')
plt.xlabel('# of epochs')
plt.show()
model.save('.\\static_model\\static_my_model.h5')

预测的分模块源码

这个是为了方便可以独立加载不同的训练参数的模型来进行测试

from keras.models import Sequential
from keras.layers import Conv2D, Flatten, Dense,MaxPool2D
import numpy as np
from keras.preprocessing import image
from keras.callbacks import EarlyStopping, ModelCheckpoint
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
from keras.models import load_model
import ostry:from tensorflow.python.util import module_wrapper as deprecation
except ImportError:from tensorflow.python.util import deprecation_wrapper as deprecation
deprecation._PER_MODULE_WARNING_LIMIT = 0import tensorflow as tf
gpus = tf.config.experimental.list_physical_devices(device_type='GPU')
tf.config.experimental.set_virtual_device_configuration(gpus[0], [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=2048)])  # 限制最大显存使用1Gdef ImagePrediction(loc):testlen=len(os.listdir(loc))print("len(os.listdir(loc))=",len(os.listdir(loc)))pre_array=np.zeros(testlen)labels_array=np.loadtxt(".\\dataset\\label.txt",usecols=0)human_labels_array = np.loadtxt(".\\dataset\\human_label.txt", usecols=0)#print("labels_array=",labels_array)for i in range(1,len(os.listdir(loc))+1):path=loc+"\\img{}.jpg".format(i)#print("path=",path)test_image = image.load_img(path, target_size = (128,128))#plt.axis('off')#plt.imshow(test_image)test_image = image.img_to_array(test_image)test_image = np.expand_dims(test_image, axis =0)result = model.predict(test_image)if result[0][0] == 1:predictions = 'Real'pre_array[i-1]=1else:predictions = 'Fake'pre_array[i - 1] =-1#print('Prediction: ',predictions)print("第{}幅图:{},pred={}".format(i,predictions,pre_array[i - 1]))#print("pre_array=",pre_array)turenum=0human_truenum=0for i in range(testlen):if pre_array[i]==labels_array[i]:turenum+=1print("第{}个正确".format(i+1))if human_labels_array[i]==labels_array[i]:human_truenum+=1#print("第{}个正确".format(i))accuracy=turenum/testlen##Ref_accuarcy=human_truenum/testlenprint("Ref_accuarcy=",Ref_accuarcy,"accuracy=",accuracy,"正确个数=",turenum)#下面填写图片路径进行测试model = load_model('.\\static_model\\static_my_model.h5')
img =".\\dataset\\real_and_fake_face_testing\\real_and_fake_face_testing"
test_image_1 = ImagePrediction(img)

神经网络学习——图像篡改相关推荐

  1. 基于深度学习的图像篡改识别

    文章目录 为什么要做图像篡改识别 图像篡改的类型 不同篡改类型的训练和测试结果 代码框架以及通用的实验参数 高斯模糊 高斯噪音 中值滤波 二次JPEG压缩 亮度 对比度 实验总结 为什么要做图像篡改识 ...

  2. 【深度学习】卷积神经网络实现图像多分类的探索

    [深度学习]卷积神经网络实现图像多分类的探索 文章目录 1 数字图像解释 2 cifar10数据集踩坑 3 Keras代码实现流程 3.1 导入数据 3.2 浅层CNN 3.3 深层CNN 3.4 进 ...

  3. 【深度学习的数学】用神经网络进行图像分类时,为什么输出层的神经单元数量要跟分类数相同?可以采用二进制的表示方式么?

    引用文章:用神经网络进行图像分类时,为什么输出层的神经单元数量要跟分类数相同?

  4. 复旦提出ObjectFormer,收录CVPR 2022!图像篡改检测新工作!

    点击下方卡片,关注"CVer"公众号 AI/CV重磅干货,第一时间送达 Part I. 文章简介 本文中,复旦大学以人为本人工智能研究中心提出了ObjectFormer,借助视觉T ...

  5. 掌握AI图像篡改检测工具,轻松识别图片造假

    文章目录 一.前言 1.1 背景与危害 1.2会议探讨 1.3 技术先行 二.亮点技术1:AI图像篡改检测技术 2.1 传统方法Python实现步骤 2.2 合合信息--PS纂改检测体验 三.亮点技术 ...

  6. 神经网络学习到的是什么?(Python)

    作者|泳鱼 来源|算法进阶 神经网络(深度学习)学习到的是什么?一个含糊的回答是,学习到的是数据的本质规律.但具体这本质规律究竟是什么呢?要回答这个问题,我们可以从神经网络的原理开始了解. 一. 神经 ...

  7. 快速构建深度学习图像数据集,微软Bing和Google哪个更好用?

    译者 | Serene 编辑 | 明明 出品 | AI 科技大本营(公众号ID:rgznai100) [AI 科技大本营导读]在本文中,作者将利用微软的 Bing Image Search API 来 ...

  8. ​厦大等高校研究人员利用卷积神经网络学习脑电地形图表示进行分类

    脑电图(EEG)地形图表征(Electroencephalography topographical  representation, ETR)可以监测区域大脑活动,是一种可以用于探索皮层机制和联系的 ...

  9. ​利用卷积神经网络学习脑电地形图表示进行分类

    点击上面"脑机接口社区"关注我们 更多技术干货第一时间送达 脑电图(EEG)地形图表征(Electroencephalography topographical  represen ...

最新文章

  1. python3 PIL、opencv, 二进制、base64 四种图片格式转换
  2. jQuery 1.9使用$.support替代$.browser的使用方法
  3. 银行业应对信息安全威胁高危的三大原则
  4. SAP Spartacus split view右边视图的overflow属性三种不同的值
  5. C++中局部变量可以和全局变量重名吗?
  6. django 中使用 channels 实现websocket
  7. QT5开发及实例学习之二信号和槽机制
  8. cas4.0 mysql_【SSO单点系列】:CAS4.0 CAS整合SpringMVC+MyBatis实现数据库校验(04)
  9. rost反剽窃检测系统_色情、低俗信息没得治?今日头条这款检测工具,240万人都在用!...
  10. PN结是什么?PN结有什么特征?PN结的应用
  11. HTML打地鼠小游戏代码
  12. rop检查_我科成功实施首例全麻下小儿眼底荧光造影检查!
  13. 天眼查 Authorized和企查查 sign破解
  14. 小程序云开发实现微信支付完整代码
  15. 【烈日炎炎战后端】Linux(0.3万字)
  16. git+小乌龟安装教程。。
  17. migo初始化库存 s4_货物移动_初始化库存(MvT561)
  18. eagle转载自乐视大数据部高级hadoop工程师蔡华宇
  19. Window 下 VFW 视频采集与显示
  20. font-family设置

热门文章

  1. Prepared statement needs to be re-prepared
  2. OJ(vjudge)错误提示类型
  3. 数学建模 -- 蒙特卡洛算法
  4. 2021-04-09编程求1000以内的所有“完数”。所谓“完数”是指一个数恰好等于它的因子之和。例如,6是完数,因为6=1+2+3
  5. C#图片处理如何生成缩略图
  6. easyExcel导出和读取
  7. 李国庆做客王峰十问:为何大佬们突然呼唤996?
  8. shell编写倒九九表
  9. 远程访问计算机硬盘_如何通过电话远程访问计算机
  10. sparse double matlab,matlab sparse 不支持单精度矩阵 的问题