In [193]:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
In [194]:
! ls ../dat
In [195]:
import pickle
In [196]:
with open("../dat/FaceEmbeddingsDataset.p", "rb") as f:
d = pickle.load(f)
In [197]:
len(d), type(d[0]), len(d[0])
Out[197]:
In [198]:
videos = []
has_any = []
for si, sample in enumerate(d):
mtx = [r[0] for r in sample if r]
if mtx:
videos.append(np.stack(mtx))
has_any.append(si)
In [199]:
len(has_any)
Out[199]:
In [200]:
with open("../dat/Labels.p", "rb") as f:
labels = pickle.load(f)
In [201]:
labels = (np.array(labels) == 'FAKE').astype(int)
In [202]:
labels = labels[has_any]
In [ ]:
In [203]:
len(videos), len(labels)
Out[203]:
In [204]:
for vi in range(len(videos)):
missing = (30 - len(videos[vi]))
if missing > 0:
extra = np.zeros((missing, 128))
row = np.concatenate((videos[vi], extra))
videos[vi] = row
In [205]:
y[200:].float().mean()
Out[205]:
In [206]:
X = torch.from_numpy(np.stack(videos)).float()[200:]
y = torch.from_numpy(labels).long()[200:]
In [207]:
all_idx = np.arange(len(X))
np.random.shuffle(all_idx)
dev_idx = all_idx[:70]
train_idx = all_idx[70:]
train_X = X[train_idx]
train_y = y[train_idx]
dev_X = X[dev_idx]
dev_y = y[dev_idx]
In [208]:
dev_y
Out[208]:
In [ ]:
In [209]:
class BatchedIterator:
def __init__(self, X, y, batch_size):
self.X = X
self.y = y
self.batch_size = batch_size
def iterate_once(self):
for start in range(0, len(self.X), self.batch_size):
end = start + self.batch_size
yield self.X[start:end], self.y[start:end]
Testing the iterator:
In [210]:
train_iter = BatchedIterator(train_X, train_y, 303)
for batch in train_iter.iterate_once():
print(batch[0].size(), batch[1].size())
In [212]:
class SimpleFakeClassifier(nn.Module):
def __init__(self, n_layer, hidden_dim):
super().__init__()
self.lstm = nn.LSTM(128, hidden_dim, num_layers=n_layer, bidirectional=True, batch_first=True, dropout=0.2)
self.output_layer = nn.Linear(2*hidden_dim, 2)
def forward(self, X):
_, (h, c) = self.lstm(X)
h = torch.cat((h[-1], h[-2]), -1)
return self.output_layer(h)
class SimpleFakeCNNClassifier(nn.Module):
def __init__(self, filt1, filt2):
super().__init__()
#TODO
self.conv1 = nn.Conv2d(128, filt1)
self.maxpool = nn.MaxPool2d(2)
self.conv2 = nn.Conv2d()
#self.output_layer = nn.Linear(, 2)
def forward(self, X):
# todo
pass
In [213]:
model = SimpleFakeClassifier(
hidden_dim=500,
n_layer=1
)
model
Out[213]:
In [214]:
for n, p in model.named_parameters():
print(n, p.size())
In [215]:
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters())
In [216]:
dev_X.dtype
Out[216]:
In [217]:
dev_pred = model(dev_X).max(axis=1)[1]
dev_acc = torch.eq(dev_pred, dev_y).sum().float() / len(dev_X)
dev_acc
Out[217]:
In [218]:
batch_size = 50
train_iter = BatchedIterator(train_X, train_y, batch_size)
dev_iter = BatchedIterator(dev_X, dev_y, batch_size)
all_train_loss = []
all_dev_loss = []
all_train_acc = []
all_dev_acc = []
n_epochs = 100
for epoch in range(n_epochs):
# training loop
for bi, (batch_x, batch_y) in enumerate(train_iter.iterate_once()):
y_out = model(batch_x)
loss = criterion(y_out, batch_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# one train epoch finished, evaluate on the train and the dev set (NOT the test)
train_out = model(train_X)
train_loss = criterion(train_out, train_y)
all_train_loss.append(train_loss.item())
train_pred = train_out.max(axis=1)[1]
train_acc = torch.eq(train_pred, train_y).sum().float() / len(train_X)
all_train_acc.append(train_acc)
dev_out = model(dev_X)
dev_loss = criterion(dev_out, dev_y)
all_dev_loss.append(dev_loss.item())
dev_pred = dev_out.max(axis=1)[1]
dev_acc = torch.eq(dev_pred, dev_y).sum().float() / len(dev_X)
all_dev_acc.append(dev_acc)
#print(f"Epoch: {epoch}\n train accuracy: {train_acc} train loss: {train_loss}")
#print(f" dev accuracy: {dev_acc} dev loss: {dev_loss}")
In [219]:
dev_pred = model(dev_X).max(axis=1)[1]
dev_acc = torch.eq(dev_pred, dev_y).sum().float() / len(dev_X)
print(dev_acc)
import pandas as pd
s = pd.DataFrame(zip(list(dev_y.data.numpy()), list(dev_pred.data.numpy())), columns=['reference', 'prediction'])
s.groupby(['reference', 'prediction']).size().unstack()
Out[219]:
In [220]:
train_pred = model(train_X).max(axis=1)[1]
train_acc = torch.eq(train_pred, train_y).sum().float() / len(train_X)
print(train_acc)
import pandas as pd
s = pd.DataFrame(zip(list(train_y.data.numpy()), list(train_pred.data.numpy())), columns=['reference', 'prediction'])
s.groupby(['reference', 'prediction']).size().unstack()
Out[220]:
In [ ]:
In [221]:
plt.plot(all_train_loss, label='train')
plt.plot(all_dev_loss, label='dev')
plt.legend()
Out[221]:
In [222]:
plt.plot(all_train_acc, label='train')
plt.plot(all_dev_acc, label='dev')
plt.legend()
Out[222]:
In [ ]:
In [223]:
use_cuda = torch.cuda.is_available()
print(use_cuda)
Moving things manually to the GPU:
This should be automatically handled by your code the following way:
In [ ]:
if use_cuda:
model = model.cuda()
criterion = criterion.cuda()