<jupyter_start><jupyter_text>Implementar o Conditional GAN- Usar Conditional GAN: [Conditional Generative Adversarial Nets](https://arxiv.org/abs/1411.1784) com o dataset criado a partir de um grafo causal implícito  Construir o Dataset<jupyter_code>import numpy as np
import pandas as pd<jupyter_output><empty_output><jupyter_text>![](../images/causal_graph.png)<jupyter_code>n_samples = 60000
genero = np.random.choice([0,1],size=n_samples,p=[0.53,0.47]).reshape(n_samples,1)
idade = np.random.choice([0,1],size=n_samples,p=[0.65,0.35]).reshape(n_samples,1)
regiao = np.random.choice([0,1,2,3],size=n_samples,p=[0.2,0.3,0.4,0.1]).reshape(n_samples,1)
def gen_bigode(genero,idade):
    prob_bigode_velho = [0.4,0.6]
    prob_bigode_novo = [0.55,0.45]
    bigode = np.zeros(shape=(genero.shape[0],1))
    for i in range(genero.shape[0]):
        if genero[i] == 1 and idade[i]==1:
            bigode[i] = np.random.choice([0,1],p=prob_bigode_velho)
        elif genero[i] == 1 and idade[i]==0:
            bigode[i] = np.random.choice([0,1],p=prob_bigode_novo)
    return bigode

def gen_careca(genero,idade):
    prob_careca_velho = [0.3,0.7]
    prob_careca_novo = [0.8,0.2]
    careca = np.zeros(shape=(genero.shape[0],1))
    for i in range(genero.shape[0]):
        if genero[i] == 1 and idade[i]==1:
            careca[i] = np.random.choice([0,1],p=prob_careca_velho)
        if genero[i] == 1 and idade[i]==0:
            careca[i] = np.random.choice([0,1],p=prob_careca_novo)
    return careca

def gen_cabelo(regiao,careca):
    prob_cabelo_america = [0.45,0.40,0.15]
    prob_cabelo_europa = [0.35,0.40,0.25]
    prob_cabelo_asia = [0.9,0.09,0.01]
    prob_cabelo_oceania = [0.4,0.5,0.1]
    cabelo = np.zeros(shape=(regiao.shape[0],1))
    for i in range(regiao.shape[0]):
        if careca[i] == 0 and regiao[i]==0:
            cabelo[i] = np.random.choice([0,1,2],p=prob_cabelo_america)
        elif careca[i] == 0 and regiao[i]==1:
            cabelo[i] = np.random.choice([0,1,2],p=prob_cabelo_europa)
        elif careca[i] == 0 and regiao[i]==2:
            cabelo[i] = np.random.choice([0,1,2],p=prob_cabelo_asia)
        elif careca[i] == 0 and regiao[i]==3:
            cabelo[i] = np.random.choice([0,1,2],p=prob_cabelo_oceania)
        elif careca[i] == 1:
            cabelo[i] = 3
    return cabelo

def gen_oculos(idade):
    prob_oculos_velho = [0.4,0.6]
    prob_oculos_novo = [0.8,0.2]
    oculos = np.zeros(shape=(idade.shape[0],1))
    for i in range(idade.shape[0]):
        if idade[i] == 1:
            oculos[i] = np.random.choice([0,1],p=prob_oculos_velho)
        elif idade[i] == 0:
            oculos[i] = np.random.choice([0,1],p=prob_oculos_novo)
    return oculos
bigode = gen_bigode(genero,idade)
oculos = gen_oculos(idade)
careca = gen_careca(genero,idade)
cabelo = gen_cabelo(regiao,careca)
X_features = np.concatenate((genero,idade,cabelo,regiao,oculos,bigode,careca),axis=1)
df_num_ = pd.DataFrame(data=X_features,columns=['genero','idade','cabelo','regiao','oculos','bigode','careca']).astype(int)
df_num = df_num_[['genero','idade','oculos','bigode','careca']].copy()
df_num = pd.concat([df_num,pd.get_dummies(df_num_['regiao'],prefix='regiao',prefix_sep='_')],axis=1)
df_num = pd.concat([df_num,pd.get_dummies(df_num_['cabelo'],prefix='cabelo',prefix_sep='_')],axis=1)
df_num.head(2)
tradutor = {"genero":{0:"mulher",1:"homem"},
           "idade":{0:"novo",1:"velho"},
            "cabelo":{0:"escuro",1:"claro",2:"vermelho",3:"ausente"},
            "regiao":{0:"america",1:"europa",2:"asia",3:"oceania"},
            "oculos":{0:"sem oculos",1:"com oculos"},
            "bigode":{0:"sem bigode",1:"com bigode"},
            "careca":{0:"nao",1:"sim"}
           }
df_text = df_num_.copy()
for col in df_num_.columns:
    df_text[col] = df_num_[col].map(tradutor[col])
df_text.head()
print(f"Mulheres com bigode: {df_num[(df_num['genero']==0)&(df_num['bigode']==1)].shape[0]}")
print(f"Mulheres carecas: {df_num[(df_num['genero']==0)&(df_num['careca']==1)].shape[0]}")
print(f"Carecas com cabelo: {df_num[(df_num['careca']==1)&(df_num['cabelo_3']!=1)].shape[0]}")<jupyter_output>Mulheres com bigode: 0
Mulheres carecas: 0
Carecas com cabelo: 0<jupyter_text>--- Funções de auxílio<jupyter_code>def plot_losses(losses_his):
    plt.figure(figsize=(20,8))
    plt.subplot(221)
    plt.plot(losses_his[0])
    plt.grid(True)
    plt.xlabel('Epochs')
    plt.ylabel('Loss: Gerador')
    plt.subplot(222)
    plt.plot(losses_his[1])
    plt.grid(True)
    plt.xlabel('Epochs')
    plt.ylabel('Loss: Discriminador')
    plt.subplot(223)
    plt.plot(losses_his[2])
    plt.grid(True)
    plt.xlabel('Epochs')
    plt.ylabel('Loss: D real')
    plt.subplot(224)
    plt.plot(losses_his[3])
    plt.grid(True)
    plt.xlabel('Epochs')
    plt.ylabel('Loss: D fake')
#     plt.savefig('images/losses_plot',quality=100)
    plt.show()<jupyter_output><empty_output><jupyter_text>---  ConditionalGAN- Label: usaremos apenas um label, `bigode`.- Gerador: receberá o ruído `z` e a label `y` e retornará o dado `G(z,y)`.- Discriminador: receberá `G(z,y)` e `z` e retornará a probabilidade do dado ser real.<jupyter_code>import torch
import torch.utils.data as Data
import torch.nn.functional as F
from torch import optim
from torch.autograd import Variable
from torch import nn
import matplotlib.pyplot as plt
import seaborn as sns
# probabilidade de ocorre bigode=1 no dataset
rho = df_num[df_num["bigode"]==1].shape[0]/df_num.shape[0]
rho
X_data = df_num.drop("bigode",axis=1).copy().values
y_data = pd.get_dummies(df_num["bigode"]).values.reshape(X_data.shape[0],2)
X_tc = torch.Tensor(X_data).type(torch.FloatTensor)
y_tc = torch.Tensor(y_data).type(torch.FloatTensor)
print(X_tc.shape, X_tc.type(),y_tc.shape, y_tc.type())
Z_dim,h_dim,X_dim,y_dim = [100,50,X_tc.shape[1],y_tc.shape[1]]

# Arquitetura do Gerador
class GNet(torch.nn.Module):
    def __init__(self):
        super(GNet,self).__init__()
        self.hidden = torch.nn.Linear(Z_dim+y_dim, h_dim)
        self.out = torch.nn.Linear(h_dim, X_dim)
    
    def forward(self,z,l):
        h = F.relu(self.hidden(torch.cat((z,l),dim=1)))
        h = nn.Dropout(p=0.7)(h)
        X = torch.sigmoid(self.out(h))
        return X

# Arquitetura do Discriminador
class DNet(torch.nn.Module):
    def __init__(self):
        super(DNet,self).__init__()
        self.hidden = torch.nn.Linear(X_dim+y_dim, h_dim)
        self.out = torch.nn.Linear(h_dim, 1)
    
    def forward(self,X,l):
        h = F.relu(self.hidden(torch.cat((X,l),dim=1)))
        h = nn.Dropout(p=0.7)(h)
        y = torch.sigmoid(self.out(h))
        return y
# Instanciamos as redes
G = GNet().cuda()
D = DNet().cuda()

# Definimos os otimizadores
lrg,lrd = [1e-3,1e-3]
G_optim = optim.Adam(G.parameters())
D_optim = optim.Adam(D.parameters())

def reset_grad():
    G_optim.zero_grad()
    D_optim.zero_grad()
    
batch = X_tc.shape[0]
ones  = Variable(torch.ones(batch, 1)).cuda()
zeros = Variable(torch.zeros(batch, 1)).cuda()
D_loss_real_func = nn.BCELoss()  
D_loss_fake_func = nn.BCELoss()
G_loss_func = nn.BCELoss()

def nets_test(n_sample,G,D):
    z = Variable(torch.randn(n_sample, Z_dim)).cuda()
    x = torch.Tensor(X_tc[:n_sample]).cuda()
    l = torch.Tensor(y_tc[:n_sample]).cuda()
    g = G(z,l)
    D_real = D(x,l)
    D_fake = D(g,l)
    print('Average D_real  {:.6f}| Std D_real  {:.6f}'.format(D_real.mean(),D_real.std()))
    print('Average D_fake  {:.6f}| Std D_fake  {:.6f}'.format(D_fake.mean(),D_fake.std()))
%%time
epochs = 10000

G_his, D_his, D_real_his, D_fake_his = [[],[],[],[]]
losses_his = [G_his,D_his,D_real_his,D_fake_his] 

for epoch in range(epochs):
    # Amostragem de dados
    z = Variable(torch.randn(batch, Z_dim)).cuda()
    X = X_tc.cuda()
    l = y_tc.cuda()
    # Dicriminador
    G_sample = G(z,l)
    D_real = D(X,l)
    D_fake = D(G_sample,l)
    D_loss_real = D_loss_real_func(D_real, ones)
    D_loss_fake = D_loss_fake_func(D_fake, zeros)
    D_loss = D_loss_real + D_loss_fake
    D_loss.backward()
    D_optim.step()
    reset_grad()
    # Generador
    z = Variable(torch.randn(batch, Z_dim)).cuda()
    G_sample = G(z,l)
    D_fake = D(G_sample,l)
    G_loss = G_loss_func(D_fake, ones)
    G_loss.backward()
    G_optim.step()
    reset_grad()
    # Recolher dados das funções de perda
    G_his.append(G_loss.data)
    D_his.append(D_loss.data)
    D_fake_his.append(D_loss_fake.data)
    D_real_his.append(D_loss_real.data)
    # Mostrar dados ao longo das epochs
    if epoch % int(epochs/4) == 0 and epoch > 0:
        print('Epoch-{}| Average D_loss: {:.5f}| Average G_loss: {:.5f}| Average D_real: {:.5f} | Average D_fake: {:.5f}'.format(
            epoch, D_loss.data, G_loss.data, D_loss_real.data, D_loss_fake.data))
        nets_test(20000,G,D)
nets_test(60000,G,D)
plot_losses(losses_his)<jupyter_output><empty_output><jupyter_text>Reproduzindo dados como os do dataset inicial<jupyter_code>oh = np.eye(2)
batch = X_tc.shape[0]
l_s = np.random.choice([0,1],p=[1-rho,rho],size=(batch))
l_s_ = torch.Tensor(oh[l_s]).type(torch.FloatTensor).cuda()
l_s = torch.Tensor(l_s).type(torch.FloatTensor).reshape(batch,1).cuda()
g = G(Variable(torch.randn(batch, Z_dim)).cuda(),l_s_)
x_gen = torch.cat((g[:,0:3],l_s,g[:,3:]),dim=1)
df_g = pd.DataFrame(data=np.round(x_gen.cpu().data.numpy(),0),columns=df_num.columns).astype(int)
#dataset fake
print('mulheres de bigode: {}| homens de bigode: {}'\
      .format(df_g[(df_g['genero']==0)&(df_g['bigode']==1)].shape[0],
             df_g[(df_g['genero']==1)&(df_g['bigode']==1)].shape[0]))
print('novos de oculos: {}| velhos de oculos: {}'\
      .format(df_g[(df_g['idade']==0)&(df_g['oculos']==1)].shape[0],
             df_g[(df_g['idade']==1)&(df_g['oculos']==1)].shape[0]))
#dataset real
print('mulheres de bigode: {}| homens de bigode: {}'\
      .format(df_num[(df_num['genero']==0)&(df_num['bigode']==1)].shape[0],
             df_num[(df_num['genero']==1)&(df_num['bigode']==1)].shape[0]))
print('novos de oculos: {}| velhos de oculos: {}'\
      .format(df_num[(df_num['idade']==0)&(df_num['oculos']==1)].shape[0],
             df_num[(df_num['idade']==1)&(df_num['oculos']==1)].shape[0]))
#dataset fake
print('mulheres carecas: {}| homens carecas: {}'\
      .format(df_g[(df_g['genero']==0)&(df_g['careca']==1)].shape[0],
             df_g[(df_g['genero']==1)&(df_g['careca']==1)].shape[0]))
print('novos carecas: {}| velhos carecas: {}'\
      .format(df_g[(df_g['idade']==0)&(df_g['careca']==1)].shape[0],
             df_g[(df_g['idade']==1)&(df_g['careca']==1)].shape[0]))
#dataset real
print('mulheres carecas: {}| homens carecas: {}'\
      .format(df_num[(df_num['genero']==0)&(df_num['careca']==1)].shape[0],
             df_num[(df_num['genero']==1)&(df_num['careca']==1)].shape[0]))
print('novos carecas: {}| velhos carecas: {}'\
      .format(df_num[(df_num['idade']==0)&(df_num['careca']==1)].shape[0],
             df_num[(df_num['idade']==1)&(df_num['careca']==1)].shape[0]))
#dataset fake
print('proporcao de novos sem oculos: {:.4f}'\
      .format(df_g[(df_g['idade']==0)&(df_g['oculos']==0)].shape[0]/\
             df_g[df_g['idade']==0].shape[0]))
print('proporcao de velhos sem oculos: {:.4f}'\
      .format(df_g[(df_g['idade']==1)&(df_g['oculos']==0)].shape[0]/\
             df_g[df_g['idade']==1].shape[0]+0.001))
#dataset real
print('proporcao de novos sem oculos: {:.4f}'\
      .format(df_num[(df_num['idade']==0)&(df_num['oculos']==0)].shape[0]/\
             df_num[df_num['idade']==0].shape[0]))
print('proporcao de velhos sem oculos: {:.4f}'\
      .format(df_num[(df_num['idade']==1)&(df_num['oculos']==0)].shape[0]/\
             df_num[df_num['idade']==1].shape[0]))
for col in df_num.columns:
    print('variacao de {} em relacao ao real: {:.2%}'\
          .format(col,
                  (df_num[col].value_counts().values[0]-df_g[col].value_counts().values[0])/df_num[col].value_counts().values[0]))
for col in df_g.columns:
    plt.figure(figsize=(10,3))
    sns.distplot(df_num[col],label='Real')
    sns.distplot(df_g[col],label='Fake')
    plt.legend(loc=0)
    plt.grid(True)
    plt.show()<jupyter_output><empty_output><jupyter_text>Intervenção<jupyter_code>oh = np.eye(2)
batch = X_tc.shape[0]
l_s = np.random.choice([0,1],p=[0,1],size=(batch))
l_s_ = torch.Tensor(oh[l_s]).type(torch.FloatTensor).cuda()
l_s = torch.Tensor(l_s).type(torch.FloatTensor).reshape(batch,1).cuda()
g = G(Variable(torch.randn(batch, Z_dim)).cuda(),l_s_)
x_gen = torch.cat((g[:,0:3],l_s,g[:,3:]),dim=1)
df_g = pd.DataFrame(data=np.round(x_gen.cpu().data.numpy(),0),columns=df_num.columns).astype(int)
#dataset fake
print('mulheres de bigode: {}| homens de bigode: {}'\
      .format(df_g[(df_g['genero']==0)&(df_g['bigode']==1)].shape[0],
             df_g[(df_g['genero']==1)&(df_g['bigode']==1)].shape[0]))
print('novos de oculos: {}| velhos de oculos: {}'\
      .format(df_g[(df_g['idade']==0)&(df_g['oculos']==1)].shape[0],
             df_g[(df_g['idade']==1)&(df_g['oculos']==1)].shape[0]))
#dataset real
print('mulheres de bigode: {}| homens de bigode: {}'\
      .format(df_num[(df_num['genero']==0)&(df_num['bigode']==1)].shape[0],
             df_num[(df_num['genero']==1)&(df_num['bigode']==1)].shape[0]))
print('novos de oculos: {}| velhos de oculos: {}'\
      .format(df_num[(df_num['idade']==0)&(df_num['oculos']==1)].shape[0],
             df_num[(df_num['idade']==1)&(df_num['oculos']==1)].shape[0]))
#dataset fake
print('mulheres carecas: {}| homens carecas: {}'\
      .format(df_g[(df_g['genero']==0)&(df_g['careca']==1)].shape[0],
             df_g[(df_g['genero']==1)&(df_g['careca']==1)].shape[0]))
print('novos carecas: {}| velhos carecas: {}'\
      .format(df_g[(df_g['idade']==0)&(df_g['careca']==1)].shape[0],
             df_g[(df_g['idade']==1)&(df_g['careca']==1)].shape[0]))
#dataset real
print('mulheres carecas: {}| homens carecas: {}'\
      .format(df_num[(df_num['genero']==0)&(df_num['careca']==1)].shape[0],
             df_num[(df_num['genero']==1)&(df_num['careca']==1)].shape[0]))
print('novos carecas: {}| velhos carecas: {}'\
      .format(df_num[(df_num['idade']==0)&(df_num['careca']==1)].shape[0],
             df_num[(df_num['idade']==1)&(df_num['careca']==1)].shape[0]))
#dataset fake
print('proporcao de novos sem oculos: {:.4f}'\
      .format(df_g[(df_g['idade']==0)&(df_g['oculos']==0)].shape[0]/\
             df_g[df_g['idade']==0].shape[0]))
print('proporcao de velhos sem oculos: {:.4f}'\
      .format(df_g[(df_g['idade']==1)&(df_g['oculos']==0)].shape[0]/\
             df_g[df_g['idade']==1].shape[0]+0.001))
#dataset real
print('proporcao de novos sem oculos: {:.4f}'\
      .format(df_num[(df_num['idade']==0)&(df_num['oculos']==0)].shape[0]/\
             df_num[df_num['idade']==0].shape[0]))
print('proporcao de velhos sem oculos: {:.4f}'\
      .format(df_num[(df_num['idade']==1)&(df_num['oculos']==0)].shape[0]/\
             df_num[df_num['idade']==1].shape[0]))
for col in df_num.columns:
    print('variacao de {} em relacao ao real: {:.2%}'\
          .format(col,
                  (df_num[col].value_counts().values[0]-df_g[col].value_counts().values[0])/df_num[col].value_counts().values[0]))
for col in df_g.columns:
    plt.figure(figsize=(10,3))
    sns.distplot(df_num[col],label='Real')
    sns.distplot(df_g[col],label='Fake')
    plt.legend(loc=0)
    plt.grid(True)
    plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.21643728901584003, 'fraction_numerical': 0.029862373409504026, 'mean_word_length': 4.350816255644321, 'pattern_counts': {'":': 7, '<': 24, '<?xml version=': 0, '>': 25, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '458734', 'license': 'Apache-2.0', 'n_tokens_mistral': 6755, 'n_tokens_neox': 6543, 'n_words': 842, 'path': 'GAN/ConditionalGan_causal_implicit_graph.ipynb', 'repo_name': 'onimaru/Generative_models', 'size': '15404'}