import torch
import numpy as np
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as Data
from torch.utils.data import Dataset, DataLoader
sentence_list = ['i say hello', 'you eat egg', 'he can sing', 'she will go']
words = ' '.join(sentence_list).split(' ')
all_words = list(set(words))
print(all_words)
all_words_len = len(all_words)
print(all_words_len)
index2word = { k: v for k, v in enumerate( all_words) }
word2index = { v: k for k, v in enumerate( all_words) }
print( index2word)
print( word2index)
def make_data( sentence_list) :
input_batch = [ ]
output_batch = [ ]
for sentence in sentence_list:
word = sentence.split( ' ' )
input = [ word2index[ n] for n in word[ :-1] ]
output = word2index[ word[ -1] ]
input_batch.append( np.eye( all_words_len) [ input] )
output_batch.append( output)
print( input_batch)
print( output_batch)
return torch.Tensor( input_batch) , torch.LongTensor( output_batch)
input_batch, output_batch = make_data( sentence_list)
print( '-------' )
print( input_batch, output_batch)
dataset = Data.TensorDataset( input_batch, output_batch)
dataloader = Data.DataLoader( dataset= dataset,
batch_size = 2 ,
drop_last = True,
shuffle = False)
for x, y in dataloader:
print( x, x.shape)
print( y, y.shape)
print( '----' )
class MyRNN( nn.Module) :
def __init__( self) :
super( MyRNN, self) .__init__( )
self.rnn = nn.RNN( input_size= all_words_len, hidden_size = 6 )
self.fc = nn.Linear( in_features= 6 , out_features = all_words_len)
def forward( self, input) :
input = input.transpose( 0 , 1 )
out, h_0i = self.rnn( input)
out = out[ -1]
model = self.fc( out)
return model
model = MyRNN( )
class FGM( ) :
def __init__( self, model) :
self.model = model
self.backup = { }
def attack( self, epsilon = 1 ., emb_name = 'emb' ) :
for name, param in self.model.named_parameters( ) :
if param.requires_grad and emb_name in name:
self.backup[ name] = param.data.clone( )
norm = torch.norm( param.grad)
if norm != 0 :
r_at = epsilon * param.grad / norm
param.data.add_( r_at)
def restore( self, emb_name = 'emb' ) :
for name, param in self.model.named_parameters( ) :
if param.requires_grad and emb_name in name:
assert name in self.backup
param.data = self.backup[ name]
self.backup = { }
loss_fn = nn.CrossEntropyLoss( )
optimizer = optim.Adam( model.parameters( ) , lr = 0.01 )
fgm = FGM( model)
for epoch in range( 10 ) :
for x, y in dataloader:
out1 = model( x)
loss = loss_fn( out1,y)
loss.backward( )
fgm.attack( )
out1 = model( x)
loss_sum = loss_fn( out1,y)
loss_sum.backward( )
fgm.restore( )
optimizer.step( )
model.zero_grad( )
print( loss)
print( loss_sum)
correct = 0
total = 0
with torch.no_grad( ) :
for x, y in dataloader:
outputs = model( x)
print( outputs)
_, predicted = torch.max( outputs.data, 1 )
total += y.size( 0 )
correct += ( predicted == y) .sum( ) .item( )
print( correct)
print( 'Accuracy of the network : %d %%' % ( 100 * correct / total))