روش های تولید دیپ فیک (جعل عمیق) و ساختار آنها — راهنمای جامع
اگر اخبار دنیای فناوری را در یک سال اخیر دنبال کرده باشید، به احتمال زیاد با اصطلاح «دیپ فیک» (DeepFake | جعل عمیق) آشنا شدهاید. سیستمهای دیپ فیک (جعل عمیق) که سیستمهای مبتنی بر «یادگیری عمیق» (Deep Learning) و «یادگیری ماشین» (Machine Learning) محسوب میشوند، در نگاه اول شاید فناوری سرگرم کنندهای به نظر برسند، با این حال، با بررسی دقیق کاربرد آنها میتوان دریافت از این دسته از فناوریها برای جابجایی چهره افراد مختلف و «تحریف کردن» (Doctoring) فایلهای ویدیوئی مورد استفاده قرار میگیرند.
در چند سال اخیر، شاهد ظهور فناوریهای هوشمند و در عین خطرناکی در سطح اینترنت هستیم؛ به جرأت میتوان گفت که از میان فناوریهای ترسناک و خطرناک موجود در سطح اینترنت، قابلیت گول زدن افراد با محتویات جعلی و غیر واقعی توسط دیپ فیک (جعل عمیق)، یکی از رعبآورترین سناریوهای استفاده از فناوریهای مبتنی بر هوش مصنوعی محسوب میشود. تمامی فناوریها این قابلیت را دارند که برای مقاصد خصمانه یا مفید مورد استفاده قرار بگیرند، فناوریهای دیپ فیک (جعل عمیق) نیز از این قاعده مستثنی نیستند و علاوه بر کاربردهای خصمانه، پتانسیل استفاده در کاربردهای مفید (نظیر تجاری) را دارند.
اصطلاح دیپ فیک به ویدئوها و صداهای جعلی و تولید شده به وسیله کامپیوتر اطلاق میشود که متمایز ساختن آنها از محتویات واقعی (Genuine) و بدون تغییر (Unaltered) بسیار سخت است. فناوریهای دیپ فیک جهت تغییر فایلهای ویدئویی، معادل نرمافزار فتوشاپ برای تصاویر دیجیتالی محسوب میشوند.
دیپ فیک (جعل عمیق)، که از ترکیب دو واژه دیپ (معادل انگلیسی Deep و به معنای عمیق) و فیک (معادل انگلیسی Fake به معنای جعل) تشکیل شده است، سیستمهای مبتنی بر «هوش مصنوعی» (Artificial Intelligence) محسوب میشوند که برای «سنتز یا تولید تصاویر انسان» (Human Image Synthesis) مورد استفاده قرار میگیرند.
در سیستمهای دیپ فیک یا جعل عمیق، معمولا از دسته خاصی از الگوریتمهای یادگیری ماشین به نام «شبکههای مولد تخاصمی» (Generative Adversarial Networks) جهت «ترکیب کردن» (Combine) و «برهمنهی» (Superimpose) تصاویر و ویدئوهای موجود، روی مجموعهای از تصاویر یا ویدئوهای «منبع» (Source) استفاده میشود.
به دلیل وجود چنین ویژگی مشخصهای در سیستمهای دیپ فیک یا جعل عمیق، از این دسته از سیستمها برای تولید محتویات «چند رسانهای» (Multimedia) با نیت خصمانه استفاده میشود. از جمله مهمترین کاربردهای خصمانه سیستمهای دیپ فیک میتوان به مواردی نظیر «اخبار جعلی» (Fake News)، «فریبکاریهای خصمانه» (Malicious Hoaxes) و سایر موارد اشاره کرد.
از جمله کاربردهای خطرناک سیستمهای دیپ فیک (جعل عمیق)، تولید محتوای غیر اخلاقی جعلی با استفاده از تصاویر چهرههای مشهور دنیا و ترکیب و برهمنهی آنها با ویدئوهای غیر اخلاقی است. در این دسته از کاربردهای خصمانه دیپ فیک (جعل عمیق)، امکان تشخیص محتوای جعلی از محتوای واقعی بسیار سخت است. در نتیجه، بسیاری از افراد هنگام مشاهده ویدئوهای دیپ فیک (جعل عمیق)، به جعلی بودن محتوای آنها شک نمیکنند.
دیپ فیک (جعل عمیق | DeepFake)
دیپ فیک (جعل عمیق)، یکی از فناوریهای نوظهور مبتنی بر هوش مصنوعی است که جهت تولید یا تغییر محتویات فایلهای ویدئویی مورد استفاده قرار میگیرد؛ به گونهای که محتویات نمایش داده شده در فایلهای ویدئویی، در اصل رخ نداده است یا وجود خارجی ندارد.
نامگذاری چنین فناوریهایی به عنوان دیپ فیک (جعل عمیق)، بر اساس نام کاربری یکی از اعضای سایت Reddit (یک محیط میکروبلاگ و یکی از شبکههای اجتماعی معروف) است. این شخص که با نام کاربری deepfakes در سایت Reddit شناخته میشود، در دسامبر سال 2017 میلادی، از فناوری یادگیری عمیق برای ویرایش چهره افراد مشهور (Celebrities) و قرار دادن چهره آنها روی بازیگران فیلمهای غیر اخلاقی (و تولید ویدئوهای جعلی) استفاده کرده است.
غالب سیستمهای دیپ فیک مبتنی بر روشهای یادگیری عمیق هستند. یک بخش بزرگ از ابزارهایی که از طریق آنها ویدئوهای دیپ فیک تولید میشوند، مبتنی بر تکنیکهای خاصی به نام شبکههای مولد تخاصمی هستند. شبکههای مولد تخاصمی که به اختصار به آنها شبکههای GAN نیز گفته میشود، توسط محققی به نام Ian Goodfellow در سال 2014 ابداع شدند.
الگوریتمهای GAN از دو مدل هوش مصنوعی تشکیل میشوند؛ وظیفه یکی از این مدلها تولید محتوا (به عنوان نمونه، تولید تصاویر افراد) است. وظیفه مدل رقیب نیز این است که تشخیص دهد آیا عکس تولید شده واقعی است یا جعلی. مدل هوش مصنوعی که وظیفه تولید عکس را برعهده دارد، کار خود را از صفر آغاز میکند؛ به عبارت دیگر، تشخیص جعلی بودن تصاویر ابتدایی تولید شده توسط این مدل راحت است.
بنابراین، در ابتدای کار مدل هوش مصنوعی رقیب به راحتی قادر است میان تصاویر واقعی و جعلی تمایز ایجاد کند. با این حال، هر چقدر که زمان بیشتری میگذرد، دقت و عملکرد هر دو مدل ارتقاء پیدا میکند. در نهایت، عملکرد و دقت مدل هوش مصنوعی تولید کننده محتوا به قدری افزایش پیدا میکند که تشخیص جعلی بودن محتوای تولید شده توسط این مدل بسیار سخت میشود.
شبکههای مولد تخاصمی
شبکههای مولد تخاصمی (GAN)، کلاسی از الگوریتمهای یادگیری ماشین محسوب میشوند که در سال 2014 توسط Ian Goodfellow و همکارانش ابداع شد. در شبکههای مولد تخاصمی، دو «شبکه عصبی مصنوعی» (Artificial Neural Network) رقیب در یک بازی (این بازی معمولا از قواعد «نظریه بازی» (Game Theory) و فرم «بازی مجموع-صفر» (Zero-Sum Game) تبعیت میکند) با یکدیگر به رقابت میپردازند.
با در اختیار داشتن یک «مجموعه آموزشی» (Training Set)، مدل شبکههای مولد تخاصمی یاد میگیرد تا دادههای جدیدی تولید کند که آماره برابری با آماره دادههای آموزشی داشته باشند. به عنوان نمونه، یک مدل GAN آموزش داده شده روی تصاویر دیجیتالی، قادر است تصاویر جدیدی تولید کند که به صورت سطحی، برای ناظران انسانی واقعی به نظر میرسند و بسیاری از ویژگیهای مشخصه یک تصویر دیجیتالی واقعی را از خود نشان میدهند.
شبکههای مولد تخاصمی از دو بخش تشکیل شدهاند: «شبکههای مولد» (Generative Network) و «شبکههای متمایزگر یا تمایزی» (Discriminator). شبکههای مولد وظیفه تولید دادههای کاندید را بر عهده دارند، در حالی که شبکههای متمایزگر، وظیفه ارزیابی دادههای کاندید تولید شده را بر عهده دارند.
رقابت میان این دو شبکه، بر اساس «توزیع دادهها» (Data Distribution) صورت میگیرد. معمولا شبکههای مولد، نگاشت دادهها از «فضای نهان» (Latent Space) به یک توزیع دلخواه را یاد میگیرند؛ در حالی که شبکههای متمایزگر، دادههای کاندید تولید شده توسط شبکههای مولد را از توزیع واقعی دادهها متمایز میکنند.
هدف اصلی فاز آموزش شبکههای مولد، افزایش نرخ خطای شبکههای متمایزگر است. به عبارت دیگر، از طریق تولید دادههای کاندیدی که مدل متمایزگر قادر به تشخیص مصنوعی بودن آنها نیست، شبکههای مولد سعی میکنند تا شبکههای متمایزگر را فریب دهند.
از یک مجموعه داده شناخته شده (جعلی یا واقعی بودن دادههای این مجموعه مشخص شده است)، به عنوان مجموعه داده ابتدایی برای آموزش مدل متمایزگر استفاده میشود. در مرحله آموزش مدل متمایزگر، نمونههای موجود در مجموعه آموزشی وارد شبکه متمایزگر میشوند؛ تا زمانی که شبکه به عملکرد و دقت مطلوب دست پیدا کند. شبکه مولد بر اساس این معیار که آیا موفق به فریب دادن شبکه متمایزگر میشود یا نه، آموزش داده میشود.
همچنین، شبکه مولد معمولا یه وسیله نمونههای تصادفی که از یک فضای نهان (نظیر توزیع نرمال چند متغیره (Multivariate Normal Distribution)) نمونهگیری شدهاند، آموزش میبیند. در مرحله بعد، دادههای کاندید تولید یا سنتز شده به وسیله مدل متمایزگر ارزیابی میشوند. از الگوریتم یادگیری «پسانتشار» (BackPropagation) در هر دو مدل استفاده میشود تا شبکه مولد بتواند تصاویر بهتری تولید کند و شبکه متمایزگر نیز بتواند در متمایز کردن تصاویر واقعی از تصاویر جعلی مهارت بیشتری کسب کند.
شایان توجه است که مدل متمایزگر معمولا یک «شبکه عصبی پیچشی» (Convolutional Neural Network) است، در حالی که برای پیادهسازی مدل مولد از «شبکههای عصبی دیکانولوشن» (Deconvolutional Neural Network) استفاده میشود.
شبکههای مولد تخاصمی برای تولید ویدئوهای دیپ فیک
ویدئوهای دیپ فیک (جعل عمیق)، با استفاده از دو سیستم یا مدل هوش مصنوعی «رقابت کننده» (Competing) پدید میآیند؛ دسته اول از چنین مدلها یا سیستمهای هوش مصنوعی رقابت کننده، سیستمهای «مولد» (Generator) نام دارد و دسته دوم، سیستمهای «متمایزگر یا تمایزی» (Discriminator).
روش کار سیستمهای هوشمند تولید کننده محتوای دیپ فیک بدین صورت است که ابتدا مدلهای مولد (Generator)، یک ویدئوی جعلی تولید میکند. سپس، ویدئوی تولید شده به عنوان ورودی مدلهای متمایزگر وارد سیستم میشود. وظیفه مدل متمایزگر این است که تشخیص دهد آیا ویدئوی تولید شده واقعی است یا جعلی.
هر بار که مدل متمایزگر بتواند به درستی، جعلی بودن ویدئوها را تشخیص دهد، باز خورد یا سیگنالی در اختیار مدل مولد قرار میدهد؛ این سیگنال یا بازخورد، خطاهای مدل مولد در تولید ویدئوهای تقلبی را مشخص میکند. مدل مولد بر اساس «بازخوردهای» (Feedbacks) ایجاد شده، اقدام به تصحیح خطا و تولید ویدئوهای تقلبی جدید میکند.
همانطور که پیش از این نیز اشاره شد، از در کنار هم قرار گرفتن مدلهای مولد و متمایزگر، شبکههای مولد تخاصمی شکل خواهد گرفت. اولین قدم در پیادهسازی یک مدل شبکههای مولد تخاصمی یا GAN، شناسایی خروجی مطلوب و تولید یک مجموعه داده آموزشی برای مدل مولد است. به محض اینکه عملکرد و دقت مدل مولد در تولید ویدئوهای جعلی به سطح مطلوبی برسد، ویدئوهای تولید شده به عنوان ورودی مدل متمایزگر عمل خواهند کرد.
همانطور که به مرور زمان عملکرد مدل مولد در تولید ویدئوهای جعلی افزایش پیدا میکند، مدل متمایزگر نیز دقت بیشتری در تشخیص ویدئوهای جعلی از خود نشان میدهد. همچنین، با افزایش دقت و عملکرد مدل متمایزگر در تشخیص ویدئوهای جعلی، دقت مدل مولد در تولید ویدئوهای جعلی با کیفیت و نزدیک به واقعیت افزایش پیدا میکند.
تاریخچه دیپ فیک (جعل عمیق)
بیشتر سیستمهای تولید دیپ فیک معمولا در دو حوزه «مطالعات دانشگاهی» (Academic Research) و یا به وسیله افراد «آماتور» (Amateur) در جوامع آنلاین توسعه یافتهاند.
دیپ فیک در مطالعات دانشگاهی
بیشتر مطالعات دانشگاهی مرتبط با دیپ فیک در حوزه «علوم کامپیوتر» (Computer Science)، هوش مصنوعی و به طور خاص «بینایی کامپیوتر» (Computer Vision) در حال انجام است. بینایی کامپیوتر حوزهای است که بر پردازش کامپیوتری ویدئو و تصاویر دیجیتالی تمرکز دارد. اولین مطالعات تحقیقاتی معتبر در این زمینه، برنامهای کامپیوتری به نام Video Rewrite بود. این برنامه کامپیوتری که در سال 1997 منتشر شد، میتوانست تصاویر ویدیوئی صحبت کردن یک فرد خاص را به گونهای تغییر دهد که به نظر برسد این فرد، کلمات موجود در یک فایل صوتی دیگر را به زبان میآورد.
این برنامه اولین سیستم کامپیوتری محسوب میشود که فرایند «تجسم دوباره چهره» (Facial Reanimation) را به طور خودکار و از طریق روشهای یادگیری ماشین انجام میدهد. برنامهای کامپیوتری Video Rewrite، از روشهای یادگیری ماشین برای ایجاد ارتباط میان صداهای ادا شده توسط شخص موجود در تصویر و شکل چهره آنها استفاده میکند.
پروژههای تحقیقاتی معاصر در زمینه دیپ فیک (جعل عمیق)، بیشتر روی ساختن ویدئوهای «واقعنمایانهتر» (More Realistic) و همچنین، افزایش سرعت، سادگی و سطح دسترسی آنها برای عموم تمرکز دارند. برنامه Face2Face، که در سال 2016 منتشر شد، تصاویر ویدئویی چهره یک شخص را به گونهای تغییر میدهد که گویا در حال تقلید حالات چهره شخص دیگری است.
در ادامه، سه نمونه از سیستمهای تولید ویدئوهای دیپ فیک که از مطالعات دانشگاهی نشأت گرفتهاند، مورد بررسی قرار گرفته میشود.
یادگیری همگامسازی دقیق لب در ویدئو با استفاده از فایلهای صوتی
در این مثال، کاربردی از مطالعات دانشگاهی مرتبط با دیپ فیک ارائه خواهد شد. در سال 2017، نتایج یک پروژه دانشگاهی مرتبط با جعل عمیق، تحت عنوان Synthesizing Obama منتشر شد. در این برنامه، با در اختیار داشتن صدای باراک اوباما (رئیس جمهور پیشین آمریکا)، یک ویدئوی دیپ فیکِ با کیفیت از صحبت کردن این شخصیت، به همراه «همگامسازی دقیق لب» (Accurate Lip Sync) و به زبان آوردن کلمات موجود در یک فایل صوتی دیگر (از باراک اوباما) ارائه شده است.
با آموزش این سیستم روی ساعتها سخنرانی هفتگی اوباما، مدل «شبکه عصبی بازگشتی» (Recurrent Neural Network)، نگاشت از ویژگیهای خام صوتی به حالات دهان را یاد میگیرد. نتایج ارائه شده، ویدئوهای به مراتب واقعنمایانهتری را نسبت به پروژههای مشابه نشان میدهد. بخشی از کدهای لازم برای پیادهسازی این روش در زبان پایتون در ادامه نمایش داده شده است. شایان توجه است که برای اجرای صحیح کدهای نمایش داده شده، ابتدا لازم است فایلهای صوتی ورودی به سیستم «نرمالسازی» (Normalize) شوند. جهت دریافت توضیحات لازم برای اجرای کدها، به لینک [+] مراجعه شود.
فایل util.py [+]:
1import numpy as np
2import sys
3import tensorflow as tf
4
5import math
6import struct
7import argparse
8import time
9import os
10import cPickle
11import random
12import platform
13import glob
14
15plat = platform.dist()[0]
16if plat == "Ubuntu":
17 base = "/home/supasorn/"
18else:
19 base = "/projects/grail/supasorn2nb/"
20
21def readSingleInt(path):
22 with open(path) as f:
23 return int(f.readline())
24
25def readCVFloatMat(fl):
26 f = open(fl)
27 t = struct.unpack('B', f.read(1))[0]
28 if t != 5:
29 return 0
30 h = struct.unpack('i', f.read(4))[0]
31 w = struct.unpack('i', f.read(4))[0]
32 return np.reshape(np.array(struct.unpack('%df' % (h * w), f.read(4 * h * w)), float), (h, w))
33
34def _str_to_bool(s):
35 if s.lower() not in ['true', 'false']:
36 raise ValueError('Need bool; got %r' % s)
37 return s.lower() == 'true'
38
39def add_boolean_argument(parser, name, default=False):
40 group = parser.add_mutually_exclusive_group()
41 group.add_argument(
42 '--' + name, nargs='?', default=default, const=True, type=_str_to_bool)
43 group.add_argument('--no' + name, dest=name, action='store_false')
44
45def normalizeData(lst, savedir, name, varnames, normalize=True):
46 allstrokes = np.concatenate(lst)
47 mean = np.mean(allstrokes, 0)
48 std = np.std(allstrokes, 0)
49
50 f = open(savedir + "/" + name + ".txt", "w")
51 minv = np.min(allstrokes, 0)
52 maxv = np.max(allstrokes, 0)
53
54 if not isinstance(normalize, list):
55 normalize = [normalize] * len(mean)
56
57 for i, n in enumerate(varnames):
58 if normalize[i]:
59 f.write(n + "\n mean: %f\n std :%f\n min :%f\n max :%f\n\n" % (mean[i], std[i], minv[i], maxv[i]))
60 else:
61 f.write(n + "\n mean: %f (-> 0)\n std :%f (-> 1)\n min :%f\n max :%f\n\n" % (mean[i], std[i], minv[i], maxv[i]))
62 mean[i] = 0
63 std[i] = 1
64
65 np.save(savedir + '/' + name + '.npy', {'min': minv, 'max': maxv, 'mean': mean, 'std': std})
66 for i in range(len(lst)):
67 lst[i] = (lst[i] - mean) / std
68
69 f.close()
70 return mean, std
71
72
73class TFBase(object):
74 def __init__(self):
75 np.random.seed(42)
76 random.seed(42)
77 self.parser = argparse.ArgumentParser()
78 self.addDefaultParameters()
79
80 def addDefaultParameters(self):
81 self.parser.add_argument('--num_epochs', type=int, default=300,
82 help='number of epochs')
83 self.parser.add_argument('--save_every', type=int, default=10,
84 help='save frequency')
85 self.parser.add_argument('--grad_clip', type=float, default=10.,
86 help='clip gradients at this value')
87 self.parser.add_argument('--learning_rate', type=float, default=0.001,
88 help='learning rate')
89 self.parser.add_argument('--decay_rate', type=float, default=1,
90 help='decay rate for rmsprop')
91 self.parser.add_argument('--keep_prob', type=float, default=1,
92 help='dropout keep probability')
93
94 self.parser.add_argument('--save_dir', type=str, default='',
95 help='save directory')
96 self.parser.add_argument('--usetrainingof', type=str, default='',
97 help='trainingset')
98
99 add_boolean_argument(self.parser, "reprocess")
100 add_boolean_argument(self.parser, "normalizeinput", default=True)
101
102 def normalize(self, inps, outps):
103 meani, stdi = normalizeData(inps["training"], "save/" + self.args.save_dir, "statinput", ["fea%02d" % x for x in range(inps["training"][0].shape[1])], normalize=self.args.normalizeinput)
104 meano, stdo = normalizeData(outps["training"], "save/" + self.args.save_dir, "statoutput", ["fea%02d" % x for x in range(outps["training"][0].shape[1])], normalize=self.args.normalizeoutput)
105
106 for i in range(len(inps["validation"])):
107 inps["validation"][i] = (inps["validation"][i] - meani) / stdi;
108
109 for i in range(len(outps["validation"])):
110 outps["validation"][i] = (outps["validation"][i] - meano) / stdo;
111
112 return meani, stdi, meano, stdo
113
114 def loadData(self):
115 if not os.path.exists("save/"):
116 os.mkdir("save/")
117 if not os.path.exists("save/" + self.args.save_dir):
118 os.mkdir("save/" + self.args.save_dir)
119
120 if len(self.args.usetrainingof):
121 data_file = "data/training_" + self.args.usetrainingof + ".cpkl"
122 else:
123 data_file = "data/training_" + self.args.save_dir + ".cpkl"
124
125 if not (os.path.exists(data_file)) or self.args.reprocess:
126 print "creating training data cpkl file from raw source"
127 inps, outps = self.preprocess(data_file)
128
129 meani, stdi, meano, stdo = self.normalize(inps, outps)
130
131 if not os.path.exists(os.path.dirname(data_file)):
132 os.mkdir(os.path.dirname(data_file))
133 f = open(data_file, "wb")
134 cPickle.dump({"input": inps["training"], "inputmean": meani, "inputstd": stdi, "output": outps["training"], "outputmean":meano, "outputstd": stdo, "vinput": inps["validation"], "voutput": outps["validation"]}, f, protocol=2)
135 f.close()
136
137
138 f = open(data_file,"rb")
139 data = cPickle.load(f)
140 inps = {"training": data["input"], "validation": data["vinput"]}
141 outps = {"training": data["output"], "validation": data["voutput"]}
142 f.close()
143
144 self.dimin = inps["training"][0].shape[1]
145 self.dimout = outps["training"][0].shape[1]
146
147 self.inps, self.outps = self.load_preprocessed(inps, outps)
148 self.num_batches = {}
149 self.pointer = {}
150 for key in self.inps:
151 self.num_batches[key] = 0
152 for inp in self.inps[key]:
153 self.num_batches[key] += int(math.ceil((len(inp) - 2) / self.args.seq_length))
154 self.num_batches[key] = int(self.num_batches[key] / self.args.batch_size)
155 self.reset_batch_pointer(key)
156
157 def preprocess(self):
158 raise NotImplementedError()
159
160 def next_batch(self, key="training"):
161 # returns a randomised, seq_length sized portion of the training data
162 x_batch = []
163 y_batch = []
164 for i in xrange(self.args.batch_size):
165 inp = self.inps[key][self.pointer[key]]
166 outp = self.outps[key][self.pointer[key]]
167
168 n_batch = int(math.ceil((len(inp) - 2) / self.args.seq_length))
169
170 idx = random.randint(1, len(inp) - self.args.seq_length - 1)
171 x_batch.append(np.copy(inp[idx:idx+self.args.seq_length]))
172 y_batch.append(np.copy(outp[idx:idx+self.args.seq_length]))
173
174 if random.random() < 1.0 / float(n_batch):
175 self.tick_batch_pointer(key)
176 return x_batch, y_batch
177
178 def tick_batch_pointer(self, key):
179 self.pointer[key] += 1
180 if self.pointer[key] >= len(self.inps[key]):
181 self.pointer[key] = 0
182
183 def reset_batch_pointer(self, key):
184 self.pointer[key] = 0
185
186
187 def test(self):
188 # only use save_dir from args
189 save_dir = self.args.save_dir
190
191 with open(os.path.join("save/" + save_dir, 'config.pkl')) as f:
192 saved_args = cPickle.load(f)
193
194 if len(saved_args.usetrainingof):
195 pt = saved_args.usetrainingof
196 else:
197 pt = save_dir
198
199 with open("./data/training_" + pt + ".cpkl", "rb") as f:
200 raw = cPickle.load(f)
201
202 model = self.model(saved_args, True)
203 sess = tf.InteractiveSession()
204 saver = tf.train.Saver()
205
206 ckpt = tf.train.get_checkpoint_state("save/" + save_dir)
207 saver.restore(sess, ckpt.model_checkpoint_path)
208 print "loading model: ", ckpt.model_checkpoint_path
209
210 saved_args.input = self.args.input
211
212 self.sample(sess, saved_args, raw, pt)
213
214 def train(self):
215 with open(os.path.join("save/" + self.args.save_dir, 'config.pkl'), 'w') as f:
216 cPickle.dump(self.args, f)
217
218 with tf.Session() as sess:
219 model = self.model(self.args)
220
221 tf.initialize_all_variables().run()
222 ts = TrainingStatus(sess, self.args.num_epochs, self.num_batches["training"], save_interval = self.args.save_every, graph = sess.graph, save_dir = "save/" + self.args.save_dir)
223
224 print "training batches: ", self.num_batches["training"]
225 for e in xrange(ts.startEpoch, self.args.num_epochs):
226 sess.run(tf.assign(self.lr, self.args.learning_rate * (self.args.decay_rate ** e)))
227 self.reset_batch_pointer("training")
228 self.reset_batch_pointer("validation")
229
230
231 state = []
232 for c, m in self.initial_state:
233 state.append((c.eval(), m.eval()))
234
235 fetches = []
236 fetches.append(self.cost)
237 fetches.append(self.train_op)
238
239 feed_dict = {}
240 for i, (c, m) in enumerate(self.initial_state):
241 feed_dict[c], feed_dict[m] = state[i]
242
243 for b in xrange(self.num_batches["training"]):
244 ts.tic()
245 x, y = self.next_batch()
246
247 feed_dict[self.input_data] = x
248 feed_dict[self.target_data] = y
249
250 res = sess.run(fetches, feed_dict)
251 train_loss = res[0]
252
253 print ts.tocBatch(e, b, train_loss)
254
255 validLoss = 0
256 if self.num_batches["validation"] > 0:
257 fetches = []
258 fetches.append(self.cost)
259 for b in xrange(self.num_batches["validation"]):
260 x, y = self.next_batch("validation")
261
262 feed_dict[self.input_data] = x
263 feed_dict[self.target_data] = y
264
265 loss = sess.run(fetches, feed_dict)
266 validLoss += loss[0]
267 validLoss /= self.num_batches["validation"]
268
269 ts.tocEpoch(sess, e, validLoss)
270
271
272class TrainingStatus:
273 def __init__(self, sess, num_epochs, num_batches, logwrite_interval = 25, eta_interval = 25, save_interval = 100, save_dir = "save", graph = None):
274 if not os.path.exists(save_dir):
275 os.mkdir(save_dir)
276 #if graph is not None:
277 #self.writer = tf.train.SummaryWriter(save_dir, graph)
278 #else:
279 #self.writer = tf.train.SummaryWriter(save_dir)
280
281 self.save_dir = save_dir
282 self.model_dir = os.path.join(save_dir, 'model.ckpt')
283 #self.saver = tf.train.Saver(tf.all_variables(), max_to_keep = 0)
284 self.saver = tf.train.Saver(tf.all_variables())
285
286 lastCheckpoint = tf.train.latest_checkpoint(save_dir)
287 if lastCheckpoint is None:
288 self.startEpoch = 0
289 else:
290 print "Last checkpoint :", lastCheckpoint
291 self.startEpoch = int(lastCheckpoint.split("-")[-1])
292 self.saver.restore(sess, lastCheckpoint)
293
294 print "startEpoch = ", self.startEpoch
295
296 self.logwrite_interval = logwrite_interval
297 self.eta_interval = eta_interval
298 self.totalTask = num_epochs * num_batches
299 self.num_epochs = num_epochs
300 self.num_batches = num_batches
301 self.save_interval = save_interval
302
303 self.etaCount = 0
304 self.etaStart = time.time()
305 self.duration = 0
306
307 self.avgloss = 0
308 self.avgcount = 0
309
310 def tic(self):
311 self.start = time.time()
312
313 def tocBatch(self, e, b, loss):
314 self.end = time.time()
315 taskNum = (e * self.num_batches + b)
316
317 self.etaCount += 1
318 if self.etaCount % self.eta_interval == 0:
319 self.duration = time.time() - self.etaStart
320 self.etaStart = time.time()
321
322 etaTime = float(self.totalTask - (taskNum + 1)) / self.eta_interval * self.duration
323 m, s = divmod(etaTime, 60)
324 h, m = divmod(m, 60)
325 etaString = "%d:%02d:%02d" % (h, m, s)
326 self.avgloss += loss
327 self.avgcount += 1
328
329 if taskNum == 0:
330 with open(self.save_dir + "/avgloss.txt", "w") as f:
331 f.write("0 %f %f\n" % (loss, loss))
332
333 return "%.2f%% (%d/%d): %.3f t %.3f @ %s (%s)" % (taskNum * 100.0 / self.totalTask, e, self.num_epochs, loss, self.end - self.start, time.strftime("%a %d %H:%M:%S", time.localtime(time.time() + etaTime)), etaString)
334
335 def tocEpoch(self, sess, e, validLoss=0):
336 if (e + 1) % self.save_interval == 0 or e == self.num_epochs - 1:
337 self.saver.save(sess, self.model_dir, global_step = e + 1)
338 print "model saved to {}".format(self.model_dir)
339
340
341 lines = open(self.save_dir + "/avgloss.txt", "r").readlines()
342 with open(self.save_dir + "/avgloss.txt", "w") as f:
343 for line in lines:
344 if int(line.split(" ")[0]) >= e + 1:
345 break
346 f.write(line)
347 f.write("%d %f %f\n" % (e+1, self.avgloss / self.avgcount, validLoss))
348
349 self.avgcount = 0
350 self.avgloss = 0;
فایل اجرایی run.py [+]:
1import sys
2
3from util import *
4
5import json
6import copy
7import random
8import platform
9import bisect
10import numpy as np
11
12
13class Speech(TFBase):
14 def __init__(self):
15 super(Speech, self).__init__()
16 self.parser.add_argument('--timedelay', type=int, default=20,
17 help='time delay between output and input')
18 self.parser.add_argument('--rnn_size', type=int, default=60,
19 help='size of RNN hidden state')
20 self.parser.add_argument('--num_layers', type=int, default=1,
21 help='number of layers in the RNN')
22 self.parser.add_argument('--batch_size', type=int, default=100,
23 help='minibatch size')
24 self.parser.add_argument('--seq_length', type=int, default=100,
25 help='RNN sequence length')
26 self.parser.add_argument('--input', type=str, default='',
27 help='input for generation')
28 self.parser.add_argument('--input2', type=str, default='',
29 help='input for any mfcc wav file')
30 self.parser.add_argument('--guy', type=str, default='Obama2',
31 help='dataset')
32 self.parser.add_argument('--normalizeoutput', action='store_true')
33
34 self.args = self.parser.parse_args()
35 if self.args.save_dir == "":
36 raise ValueError('Missing save_dir')
37
38 # self.training_dir = base + "/face-singleview/data/" + self.args.guy + "/"
39 self.training_dir = "obama_data/"
40
41 self.fps = 29.97
42 self.loadData()
43 self.model = self.standardL2Model
44
45 self.audioinput = len(self.args.input2)
46 if (self.audioinput):
47 self.args.input = self.args.input2
48
49 if len(self.args.input):
50 self.test()
51 else:
52 self.train()
53
54 def createInputFeature(self, audio, audiodiff, timestamps, startframe, nframe):
55 startAudio = bisect.bisect_left(timestamps, (startframe - 1) / self.fps)
56 endAudio = bisect.bisect_right(timestamps, (startframe + nframe - 2) / self.fps)
57
58 inp = np.concatenate((audio[startAudio:endAudio, :-1], audiodiff[startAudio:endAudio, :]), axis=1)
59 return startAudio, endAudio, inp
60
61
62 def preprocess(self, save_dir):
63 files = [x.split("\t")[0].strip() for x in open(self.training_dir + "processed_fps.txt", "r").readlines()]
64
65 inps = {"training": [], "validation": []}
66 outps = {"training": [], "validation": []}
67
68 # validation = 0.2
69 validation = 0
70 for i in range(len(files)):
71 tp = "training" if random.random() > validation else "validation"
72
73 dnums = sorted([os.path.basename(x) for x in glob.glob(self.training_dir + files[i] + "}}*")])
74
75 audio = np.load(self.training_dir + "/audio/normalized-cep13/" + files[i] + ".wav.npy")
76 audiodiff = audio[1:,:-1] - audio[:-1, :-1]
77
78 print files[i], audio.shape, tp
79 timestamps = audio[:, -1]
80
81 for dnum in dnums:
82 print dnum
83 fids = readCVFloatMat(self.training_dir + dnum + "/frontalfidsCoeff_unrefined.bin")
84 if not os.path.exists(self.training_dir + dnum + "/startframe.txt"):
85 startframe = 1
86 else:
87 startframe = readSingleInt(self.training_dir + dnum + "/startframe.txt")
88 nframe = readSingleInt(self.training_dir + dnum + "/nframe.txt")
89
90 startAudio, endAudio, inp = self.createInputFeature(audio, audiodiff, timestamps, startframe, nframe)
91
92 outp = np.zeros((endAudio - startAudio, fids.shape[1]), dtype=np.float32)
93 leftmark = 0
94 for aud in range(startAudio, endAudio):
95 audiotime = audio[aud, -1]
96 while audiotime >= (startframe - 1 + leftmark + 1) / self.fps:
97 leftmark += 1
98 t = (audiotime - (startframe - 1 + leftmark) / self.fps) * self.fps;
99 outp[aud - startAudio, :] = fids[leftmark, :] * (1 - t) + fids[min(len(fids) - 1, leftmark + 1), :] * t;
100
101 inps[tp].append(inp)
102 outps[tp].append(outp)
103
104 return (inps, outps)
105
106 def standardL2Model(self, args, infer=False):
107 if infer:
108 args.batch_size = 1
109 args.seq_length = 1
110
111 cell_fn = tf.nn.rnn_cell.LSTMCell
112 cell = cell_fn(args.rnn_size, state_is_tuple=True)
113
114 if infer == False and args.keep_prob < 1: # training mode
115 cell0 = tf.nn.rnn_cell.DropoutWrapper(cell, input_keep_prob = args.keep_prob)
116 cell1 = tf.nn.rnn_cell.DropoutWrapper(cell, input_keep_prob = args.keep_prob, output_keep_prob = args.keep_prob)
117 self.network = tf.nn.rnn_cell.MultiRNNCell([cell0] * (args.num_layers -1) + [cell1], state_is_tuple=True)
118 else:
119 self.network = tf.nn.rnn_cell.MultiRNNCell([cell] * args.num_layers, state_is_tuple=True)
120
121
122 self.input_data = tf.placeholder(dtype=tf.float32, shape=[None, args.seq_length, self.dimin])
123 self.target_data = tf.placeholder(dtype=tf.float32, shape=[None, args.seq_length, self.dimout])
124 self.initial_state = self.network.zero_state(batch_size=args.batch_size, dtype=tf.float32)
125
126 with tf.variable_scope('rnnlm'):
127 output_w = tf.get_variable("output_w", [args.rnn_size, self.dimout])
128 output_b = tf.get_variable("output_b", [self.dimout])
129
130 inputs = tf.split(1, args.seq_length, self.input_data)
131 inputs = [tf.squeeze(input_, [1]) for input_ in inputs]
132
133 outputs, states = tf.nn.seq2seq.rnn_decoder(inputs, self.initial_state, self.network, loop_function=None, scope='rnnlm')
134
135 output = tf.reshape(tf.concat(1, outputs), [-1, args.rnn_size])
136 output = tf.nn.xw_plus_b(output, output_w, output_b)
137 self.final_state = states
138 self.output = output
139
140 flat_target_data = tf.reshape(self.target_data,[-1, self.dimout])
141
142 lossfunc = tf.reduce_sum(tf.squared_difference(flat_target_data, output))
143 #lossfunc = tf.reduce_sum(tf.abs(flat_target_data - output))
144 self.cost = lossfunc / (args.batch_size * args.seq_length * self.dimout)
145
146 self.lr = tf.Variable(0.0, trainable=False)
147 tvars = tf.trainable_variables()
148 grads, _ = tf.clip_by_global_norm(tf.gradients(self.cost, tvars), args.grad_clip)
149 optimizer = tf.train.AdamOptimizer(self.lr)
150 self.train_op = optimizer.apply_gradients(zip(grads, tvars))
151
152 def load_preprocessed(self, inps, outps):
153 newinps = {"training": [], "validation": []}
154 newoutps = {"training": [], "validation": []}
155 for key in newinps:
156 for i in range(len(inps[key])):
157 if len(inps[key][i]) - self.args.timedelay >= (self.args.seq_length+2):
158 if self.args.timedelay > 0:
159 newinps[key].append(inps[key][i][self.args.timedelay:])
160 newoutps[key].append(outps[key][i][:-self.args.timedelay])
161 else:
162 newinps[key].append(inps[key][i])
163 newoutps[key].append(outps[key][i])
164 print "load preprocessed", len(newinps), len(newoutps)
165 return newinps, newoutps
166
167
168 def sample(self, sess, args, data, pt):
169 if self.audioinput:
170 self.sample_audioinput(sess, args, data, pt)
171 else:
172 self.sample_videoinput(sess, args, data, pt)
173
174 def sample_audioinput(self, sess, args, data, pt):
175 meani, stdi, meano, stdo = data["inputmean"], data["inputstd"], data["outputmean"], data["outputstd"]
176 audio = np.load(self.training_dir + "/audio/normalized-cep13/" + self.args.input2 + ".wav.npy")
177
178 audiodiff = audio[1:,:-1] - audio[:-1, :-1]
179 timestamps = audio[:, -1]
180
181 times = audio[:, -1]
182 inp = np.concatenate((audio[:-1, :-1], audiodiff[:, :]), axis=1)
183
184 state = []
185 for c, m in self.initial_state: # initial_state: ((c1, m1), (c2, m2))
186 state.append((c.eval(), m.eval()))
187
188 if not os.path.exists("results/"):
189 os.mkdir("results/")
190
191 f = open("results/" + self.args.input2 + "_" + args.save_dir + ".txt", "w")
192 print "output to results/" + self.args.input2 + "_" + args.save_dir + ".txt"
193 f.write("%d %d\n" % (len(inp), self.dimout + 1))
194 fetches = []
195 fetches.append(self.output)
196 for c, m in self.final_state: # final_state: ((c1, m1), (c2, m2))
197 fetches.append(c)
198 fetches.append(m)
199
200 feed_dict = {}
201 for i in range(len(inp)):
202 for j, (c, m) in enumerate(self.initial_state):
203 feed_dict[c], feed_dict[m] = state[j]
204
205 input = (inp[i] - meani) / stdi
206 feed_dict[self.input_data] = [[input]]
207 res = sess.run(fetches, feed_dict)
208 output = res[0] * stdo + meano
209
210 if i >= args.timedelay:
211 shifttime = times[i - args.timedelay]
212 else:
213 shifttime = times[0]
214 f.write(("%f " % shifttime) + " ".join(["%f" % x for x in output[0]]) + "\n")
215
216 state_flat = res[1:]
217 state = [state_flat[i:i+2] for i in range(0, len(state_flat), 2)]
218 f.close()
219
220
221def main():
222 s = Speech()
223
224if __name__ == '__main__':
225 main()
کدهای کامل و قابل استفاده برای پیادهسازی این روش در زبان پایتون و دادههای لازم جهت آموزش مدل شبکه عصبی بازگشتی، از طریق لینک [+] قابل دسترس است. شایان توجه است که برای اجرای صحیح کدها، خواندن توضیحات مرتبط با نحوه اجرای برنامه در لینک [+] ضروری است.
در ادامه، نحوه عملکرد سیستم بینایی کامپیوتر ارائه شده جهت تولید ویدئوهای دیپ فیک نمایش داده شده است:
بازسازی مدل کنترل شده یک شخص از مجموعه عظیمی از دادههای تصویری
در سال 2015، گروهی از محققین روشی را برای بازسازی یک مدل کنترل شده از اشخاص، بر اساس مجموعه عظیمی از تصاویر نمایش دهنده ویژگیهای شخصیتی آنها نظیر رفتار و ظاهر فیزیکی ارائه دادند. سیستم ارائه شده توسط این محققان، بر اساس ترکیب بدیع از روشهای بازسازی سهبُعدی چهره (3D Face Reconstruction)، ردیابی (Tracking)، همترازی (Alignment) و مدلسازی چندبافتی (Multi-Texture) پدید آمده است.
قابلیت انجام عملیات روی مجموعهای از تصاویر غیر ساخت یافته، به سیستم امکان میدهد بدون اینکه تصاویر افراد را اسکن کند، تنها با داشتن تصاویر افراد از زوایای مختلف، چهره آنها را مدلسازی کند. در ادامه، نحوه عملکرد سیستم در تولید مدلهای بازسازی چهره (نمونهای از قابلیتهای یک سیستم دیپ فیک) نمایش داده شده است:
مدلهای شبکههای عصبی خود کدگذار (AutoEncoder) برای تولید دیپ فیک
یکی از روشهای دیگر برای تولید دیپ فیک (جعل عمیق)، مدل شبکه عصبی «خود کدگذار» (AutoEncoder) نام دارد. مدل خود کدگذار، یک شبکه عصبی عمیق (Deep Neural Network) است که ورودیها را در قالب تصاویر دیجیتالی دریافت و آنها را به تعدادی مدل نمایشی کوچکتر به نام «کدگذاری» (Encoding) تبدیل میکند.
در نهایت، این مدل قادر است تا تصاویر اصلی را از روی نمایشهای تولید شده (کدگذاریها) بازسازی کند.
قرار دادن مدل تولید کننده نمایش کدگذاری (Encoding) در وسط شبکه عصبی خودکدگذار، شبکه عصبی را مجبور میکند تا به جای تولید یک پیشبینی کلاسی متناسب با داده ورودی، تصاویر بازسازی شده را خروجی دهد. چنین ساختاری، شبکه عصبی را قادر میسازد تا الگوهای موجود در تصویر نظیر شکل ابروها، فرم چهره و سایر موارد و از همه مهمتر مکان آنها در تصویر را یاد بگیرد.
سیستمهای دیپ فیک (جعل عمیق)، از سه مدل خودکدگذار برای تبدیل چهره شخص A به چهره شخص B استفاده میکند. مدل خودکدگذار اول، تصویر ورودی شخص A را کدگذاری و بازسازی میکند. مدل خودکدگذار دوم، تصویر ورودی شخص B را کدگذاری و بازسازی میکند. مدل سوم نیز، تصویر شخص A را به عنوان ورودی دریافت میکند، با این حال، تصویر بازسازی شده شخص B را به عنوان خروجی تولید میکند.
روش آموزش یک مدل شبکه عصبی خودکدگذار برای تولید دیپ فیک به صورت زیر خواهد بود:
- در مرحله اول، تصویر نویزی (تاب برداشته) شخص A وارد ماژول کدگذار (Encoder) در مدل خودکدگذار (AutoEncoder) اول میشوند. در این مرحله، مدل شبکه عصبی تلاش میکند تا بر اساس کدگذاریهای تولید شده (Encoding)، چهره شخص A را بازسازی کند. به عبارت دیگر، مدل خودکدگذار اول مجبور میشود تا چهره شخص اول را از ورودیهای نویزی بازسازی کند.
- در مرحله دوم، از ماژول کدگذار (Encoder) در مدل خودکدگذار (AutoEncoder) اول استفاده و تصویر نویزی (تاب برداشته) شخص B وارد این ماژول میشود. با این تفاوت که این دفعه مدل شبکه عصبی تلاش میکند تا بر اساس کدگذاریهای تولید شده (Encoding) توسط ماژول کدگذار (Encoder)، چهره شخص B را بازسازی کند. به عبارت دیگر، مدل خودکدگذار اول مجبور میشود تا چهره شخص دوم را از ورودیهای نویزی بازسازی کند.
- این کار چندین بار تکرار میشود تا ماژولهای کدگذار (Encoder) مربوط به شخص A و B قادر به بازسازی چهرههای مربوطه شوند. به عبارت دیگر، ماژولهای کدگذار، ویژگیهای چهره شخص A و B و بازسازی آنها را یاد میگیرند.
پس از پایان مرحله آموزش مدل شبکه عصبی خودکدگذار، تصویر شخص A وارد ماژول کدگذار (Encoder) میشود؛ با این تفاوت که، به جای استفاده از کدگذاریهای تولید شده، جهت بازسازی تصویر A، کدگذاریهای تولید شده وارد کدگشای B میشوند و از این طریق، چهره شخص B بازسازی میشود.
محدودیتهای سیستمهای تولید دیپ فیک
اگرچه نتایج حاصل از تولید ویدئوهای دیپ فیک (برای مقاصد علمی و تحقیقاتی) ممکن است برای کاربران جذاب و مهیج باشد، با این حال، استفاده از فناوریهای هوش مصنوعی و یادگیری عمیق جهت تولید ویدئوهای دیپ فیک (جعل عمیق) محدودیتهایی نیز دارند که در ادامه به آنها پرداخته خواهد شد:
- سیستم تنها در صورتی قادر به تولید ویدئوهای دیپ فیک مطلوب خواهد بود که مجموعه بزرگی از تصاویر را برای آموزش در اختیار داشته باشد. برای اینکه سیستم قادر باشد تصویر یک شخص خاص را روی یک ویدئوی خاص قرار دهد، لازم است چیزی حدود 300 الی 2000 تصویر از صورت شخص در اختیار سیستم قرار داده شود تا شبکه عصبی قادر به یادگیری و بازسازی چهره آن شخص و قرار دادن آن روی ویدئوی مورد نظر باشد.
- دادههای آموزشی استفاده شده برای پیادهسازی سیستمهای دیپ فیک، باید به خوبی نمایانگر ویژگیهای ویدئوی هدف باشد. فرض کنید که قرار باشد چهره شخص A روی چهره شخص B در یک ویدئوی خاص قرار بگیرد. در چنین حالتی، تصاویر آموزشی شخص A باید در زوایا و حالات مختلف در اختیار سیستم قرار بگیرد تا سیستم بتواند به درستی ویژگیهای چهره این شخص را یاد بگیرد. به عبارت دیگر، تصاویر لازم (از شخص A) برای آموزش سیستم باید تقریب مناسبی از زوایا و حالات چهره شخص B باشد تا سیستم بتواند همترازی تصاویر شخص A روی ویدئوی شخص B را یاد بگیرد.
- ساختن مدلهای تولید دیپ فیک (جعل عمیق)، هزینه زمانی و محاسباتی زیادی میطلبد. سیستمهای تولید دیپ فیک از ماژولهای مختلفی نظیر «تشخیص چهره» (Face Detection) و همترازی تصاویر تشکیل شدهاند. هر کدام از این ماژولها، قدرت محاسباتی قابل توجهی را به خود اختصاص خواهند داد. به عنوان نمونه، آموزش یک مدل یادگیری عمیق برای تولید دیپ فیک با کیفیت معمولی، چیزی حدود 72 ساعت زمان خواهد برد. برای آموزش چنین سیستمی، به قدرت محاسباتی بسیار زیادی نیاز است. از سوی دیگر، هر مدل دیپ فیک تولید شده، تنها قادر به قرار دادن تصویر یک شخص خاص روی ویدئو خواهد بود و برای قرار دادن تصویر یک شخص دیگر روی ویدئو، احتیاج به آموزش یک مدل دیگر خواهد بود؛ به عبارت دیگر، سیستمهای تولید دیپ فیک، مقیاسپذیری خوبی از خود نشان نمیدهند.
کاربرد سیستمهای تولید دیپ فیک در جهان واقعی
در ادامه، به برخی از مهمترین کاربردهای سیستمهای تولید دیپ فیک اشاره خواهد شد:
تولید محتوای ویدئویی
شاید یکی از فناوریهای مشابهی که پیش از این در صنعت فیلم مورد استفاده شده است، فناوری تولید محتوای ویدئویی با استفاده از «جلوههای ویژه» باشد. اگرچه این فناوری (تولید چهرههای کامپیوتری و جا به جا کردن آنها با چهره بازیگران) سالهای زیادی است که در صنعت فیلم استفاده میشود، با این حال، سادگی دسترسی دیپ فیک و هزینه به مراتب کمتر آنها نسبت به جلوههای ویژه پرهزینه، دیپ فیک را به یک انتخاب وسوسهبرانگیز و هیجانآور برای افراد مختلف، به ویژه آماتورهای علاقهمند به این حوزه تبدیل کرده است.
البته، نمیتوان منکر استفادههای متعدد این فناوری در صنعت فیلم شد. به عنوان نمونه، این قابلیت برای شرکتهای سازنده فیلمهای سینمایی وجود دارد که فیلمها را با بازیگران ناشناخته ضبط کنند و سپس، در مرحله ویرایش، تصاویر بازیگران معروف روی تصاویر ضبط شده قرار داده شود. سناریوی واقعگرایانه دیگر جهت استفاده از فناوری دیپ فیک، تغییر بازیگر فیلم بر اساس بازار فروش و یا امکان انتخاب بازیگر توسط کاربر است، بدین صورت که با استفاده از این فناوری، این امکان برای کاربران فراهم میشود تا پیش از پخش یک فیلم، بازیگر مورد علاقه خود را برای ایفای نقش انتخاب کنند.
استفاده از چهره افراد مشهور برای تبلیغات پوشاک
در این سناریو، افراد مشهور چهرههای مدل شده و کامپیوتری خود را به شرکتهای تولید پوشاک قرض میدهند تا این شرکتها بدون نیاز به فیلمبرداری کلیپهای تبلیغاتی، از چهره آنها برای تبلیغ پوشاک و وسایل جانبی استفاده کنند (قرار دادن چهره افراد معروف روی مانکنهای لباس).
تبلیغات شخصیسازی شده
در این سناریو، هنگام جستجوی اینترنت، کاربران با تبلیغات هدفداری مواجه خواهند شد که از چهره خود آنها یا افراد خانواده و نزدیکان آنها استفاده شده است. به عنوان نمونه، یک مدل کامپیوتری تولید شده با توجه به مشخصات چهره و فیزیک کاربر، در حال تبلیغ پوشاک، ساعت، عینک آفتابی و سایر وسایل جانبی نمایش داده خواهد شد.
جمعبندی
فناوریهای دیپ فیک (جعل عمیق)، یکی از جنجالبرانگیزترین فناوریهایی است که در چند سال اخیر معرفی شده است و طی این مدت کوتاه توانسته است بخشهای مختلفی از جامعه انسانی و حتی مسائل سیاسی را نیز تحت تأثیر خود قرار دهد. چنین کاربردی از فناوری ممکن است یک هاله ابهام در مورد صحت و اعتبار ویدئوهای منتشر شده در سطح وب ایجاد کند.
با این حال، ظهور دیپ فیک، جذاب بودن این فناوری و کاربردهای گسترده (و مفید) آن در حوزههای مختلف علم و فناوری را نشان داد. مدلهای یادگیری عمیق نظیر GAN و مدلهای مولد یادگیری عمیق نظیر شبکههای عصبی خودکدگذار (AutoEncoder)، به کاربران (با سطح دانش کافی از مفاهیم یادگیری ماشین) اجازه میدهند تا دادههای مصنوعی ولی واقعگرایانه تولید کنند (دادههای نظیر تصاویر دیجیتالی و ویدئو). به عبارت دیگر، این در صورتی که یکی از این الگوریتمهای هوش مصنوعی به محصول تجاری تبدیل شود، ابزاری بسیار قدرتمند در اختیار کاربران عادی قرار میدهد تا بتوانند محتوای خلاقانهای (برای استفاده در مقاصد مثبت) ایجاد کنند.
اگر نوشته بالا برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای دادهکاوی و یادگیری ماشین
- آموزش اصول و روشهای دادهکاوی (Data Mining)
- مجموعه آموزشهای هوش مصنوعی
- تفسیر مدل های یادگیری عمیق در بینایی کامپیوتر — راهنمای جامع
- نقشه دانش فناوریهای هوش مصنوعی و دسته بندی آنها — راهنمای جامع
- کدنویسی شبکه های عصبی مصنوعی چند لایه در پایتون — راهنمای کامل
- یادگیری عمیق (Deep Learning) با پایتون — به زبان ساده