How to repeat a group (pattern of shapes) across the canvas? - konvajs

I've been trying to achieve a seamless continuing brick wall across the canvas using Konva React. At the moment, I have the following code. Don't mind the repeating code, there is still clean-up to do using the Group tag. The only thing is, I do not know how I can repeat those shapes across the canvas. Does anyone have any idea?
import { Stage, Group, Layer, Path, Image, Rect, Text, Circle, Line } from 'react-konva';
import useImage from 'use-image';
export default function Main(){
const [pattern, status] = useImage('https://res.cloudinary.com/dhmpnnhd0/image/upload/v1666003977/materials/mocpex-texture.jpg')
const rows = 7
const columns = 7
const scale = 0.5
const line = 5
if(status == 'loaded'){
const baseWidth = pattern.width / columns
const baseHeight = pattern.height / rows
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<Group scaleX={0.5} scaleY={0.5}>
<Rect width={baseWidth * 2} height={baseHeight * 2} x={0} y={0} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
<Rect width={baseWidth * 1 - line / 2} height={baseHeight * 2} x={0} y={baseHeight + line} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
<Rect width={baseWidth * 2 + line * 2} height={baseHeight * 2} x={baseWidth + line} y={baseHeight / 2 + line} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
<Rect width={baseWidth * 1 - line * 2} height={baseHeight * 1} x={baseWidth / 2 + line} y={baseHeight + line} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)}></Rect>
<Rect width={baseWidth * 2} height={baseHeight * 2} x={baseWidth / 2 + line} y={baseHeight * 1.50 + line * 2} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
<Rect width={baseWidth * 1} height={baseHeight - line} x={baseWidth / 2 + line * 1} y={baseHeight * 2.5 + line * 3} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
<Rect width={baseWidth * 3} height={baseHeight * 2} x={baseWidth + line * 2} y={baseHeight * 2.5 + line * 3} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)}></Rect>
<Rect width={baseWidth * 1} height={baseHeight * 1} x={baseWidth * 1.5 + line * 2} y={baseHeight * 1.5 + line * 2} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
<Rect width={baseWidth * 2} height={baseHeight - line * 2} x={baseWidth * 1.5 + line * 2} y={baseHeight * 2 + line * 3} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
<Rect width={baseWidth} height={baseHeight} x={baseWidth * 2.5 + line * 3} y={baseHeight * 3 + line * 3} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)}></Rect>
<Rect width={baseWidth * 2} height={baseHeight * 2 - line * 2} x={baseWidth * 2.5 + line * 3} y={baseHeight * 2 + line * 3} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
<Rect width={baseWidth * 2} height={baseHeight * 3 + line * 2} x={baseWidth * 2 + line * 3} y={baseHeight * 0.5 + line} fillPatternImage={pattern} scaleX={scale} scaleY={scale} fillPatternOffsetX={getRandomNumber(pattern.width)} ></Rect>
</Group>
</Layer>
</Stage>
)
}
}
function getRandomNumber(dimension){
const min = 0;
const max = dimension;
const rand = min + Math.random() * (max - min);
return rand;
}

Related

DCGAN error: Using a target size (torch.Size([128])) that is different to the input size (torch.Size([128, 1, 5, 5])) is deprecated

I keep getting this error when trying to run a DCGAN using the EMNIST dataset, I'm fairly new to this and struggling to debug the issue
class Generator(nn.Module):
def __init__(self, ngpu):
super(Generator, self).__init__()
self.ngpu = ngpu
self.main = nn.Sequential(
# input is Z, going into a convolution
nn.ConvTranspose2d( nz, ngf * 8, 4, 1, 0, bias=False),
nn.BatchNorm2d(ngf * 8),
nn.ReLU(True),
# state size. (ngf*8) x 4 x 4
nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False),
nn.BatchNorm2d(ngf * 4),
nn.ReLU(True),
# state size. (ngf*4) x 8 x 8
nn.ConvTranspose2d( ngf * 4, ngf * 2, 4, 2, 1, bias=False),
nn.BatchNorm2d(ngf * 2),
nn.ReLU(True),
# state size. (ngf*2) x 16 x 16
nn.ConvTranspose2d( ngf * 2, ngf, 4, 2, 1, bias=False),
nn.BatchNorm2d(ngf),
nn.ReLU(True),
# state size. (ngf) x 32 x 32
nn.ConvTranspose2d( ngf, nc, 4, 2, 1, bias=False),
nn.Tanh()
# state size. (nc) x 64 x 64
)
def forward(self, input):
return self.main(input)
class Discriminator(nn.Module):
def __init__(self, ngpu):
super(Discriminator, self).__init__()
self.ngpu = ngpu
self.main = nn.Sequential(
# input is (nc) x 64 x 64
nn.Conv2d(nc, ndf, 4, 2, 1, bias=False),
nn.BatchNorm2d(ndf),
nn.LeakyReLU(0.2, inplace=True),
# state size. (ndf) x 32 x 32
nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False),
nn.BatchNorm2d(ndf * 2),
nn.LeakyReLU(0.2, inplace=True),
# state size. (ndf*2) x 16 x 16
nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
nn.BatchNorm2d(ndf * 4),
nn.LeakyReLU(0.2, inplace=True),
# state size. (ndf*4) x 8 x 8
#nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
#nn.BatchNorm2d(ndf * 8),
#nn.LeakyReLU(0.2, inplace=True),
# state size. (ndf*8) x 4 x 4
nn.Conv2d(ndf * 4, 1, 4, 1, 0, bias=False),
nn.Sigmoid()
)
def forward(self, input):
return self.main(input)
# Lists to keep track of progress
img_list = []
G_losses = []
D_losses = []
iters = 0
print("Starting Training Loop...")
# For each epoch
for epoch in range(num_epochs):
# For each batch in the dataloader
for i, data in enumerate(dataloader, 0):
############################
# (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))
###########################
## Train with all-real batch
netD.zero_grad()
# Format batch
real_cpu = data[0].to(device)
b_size = real_cpu.size(0)
label = torch.full((b_size,), real_label, dtype=torch.float, device=device)
# Forward pass real batch through D
output = netD(real_cpu).view(-1)
# Calculate loss on all-real batch
errD_real = criterion(output, label)
# Calculate gradients for D in backward pass
errD_real.backward()
D_x = output.mean().item()
## Train with all-fake batch
# Generate batch of latent vectors
noise = torch.randn(b_size, nz, 1, 1, device=device)
# Generate fake image batch with G
fake = netG(noise)
label.fill_(fake_label)
# Classify all fake batch with D
output = netD(fake.detach()).view(-1)
# Calculate D's loss on the all-fake batch
errD_fake = criterion(output, label)
# Calculate the gradients for this batch, accumulated (summed) with previous gradients
errD_fake.backward()
D_G_z1 = output.mean().item()
# Compute error of D as sum over the fake and the real batches
errD = errD_real + errD_fake
# Update D
optimizerD.step()
############################
# (2) Update G network: maximize log(D(G(z)))
###########################
netG.zero_grad()
label.fill_(real_label) # fake labels are real for generator cost
# Since we just updated D, perform another forward pass of all-fake batch through D
output = netD(fake).view(-1)
# Calculate G's loss based on this output
errG = criterion(output, label)
# Calculate gradients for G
errG.backward()
D_G_z2 = output.mean().item()
# Update G
optimizerG.step()
# Output training stats
if i % 50 == 0:
print('[%d/%d][%d/%d]\tLoss_D: %.4f\tLoss_G: %.4f\tD(x): %.4f\tD(G(z)): %.4f / %.4f'
% (epoch, num_epochs, i, len(dataloader),
errD.item(), errG.item(), D_x, D_G_z1, D_G_z2))
# Save Losses for plotting later
G_losses.append(errG.item())
D_losses.append(errD.item())
# Check how the generator is doing by saving G's output on fixed_noise
if (iters % 500 == 0) or ((epoch == num_epochs-1) and (i == len(dataloader)-1)):
with torch.no_grad():
fake = netG(fixed_noise).detach().cpu()
img_list.append(vutils.make_grid(fake, padding=2, normalize=True))
iters += 1
I'm wanting to do this with just the conv2d layers that are in use and I have tried using the .squeeze function to get it working but had no luck

How to solve the dimension error and effectively use Conv2dTranspose?

i have created a discriminator and generator file to implement GAN, however, i am facing this error.
The initial error i was facing was in the main.py file where i am calling the criterion library and passing the output and label. I solved that error using squeeze function, so that the issue of shape was resolved.
Before using squeeze , an error showed that the shapes of output and labels were not matching ( the shapes were (7,1,1,1) and (7) for the output and the label respectively.
import torch
from torch import nn
class generatorG(nn.Module):
def __init__(self):
super(generatorG, self).__init__()
self.t1 = nn.Sequential(
nn.Conv2d(in_channels = 3, out_channels = 64, kernel_size= (4,4), stride = 2,padding = 1),
nn.LeakyReLU(0.2, inplace = True)
)
self.t2 = nn.Sequential(
nn.Conv2d(in_channels= 64, out_channels = 64, kernel_size = (4,4), stride = 2,padding = 1),
nn.BatchNorm2d(64),
nn.LeakyReLU(0.2, inplace = True)
)
self.t3 = nn.Sequential(
nn.Conv2d(in_channels = 64, out_channels = 128, kernel_size = 4, stride = 2, padding =1),
nn.BatchNorm2d(128),
nn.LeakyReLU(0.2, inplace = True)
)
self.t4 = nn.Sequential(
nn.Conv2d(in_channels=128, out_channels=256, kernel_size=(4, 4), stride = 2,padding=1),
nn.BatchNorm2d(256),
nn.LeakyReLU(0.2, inplace=True)
)
self.t5 = nn.Sequential(
nn.Conv2d(in_channels=256, out_channels=512, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(512),
nn.LeakyReLU(0.2, inplace=True)
)
self.t6 = nn.Sequential(
nn.Conv2d(in_channels=512, out_channels=4000, kernel_size=(4, 4)),
nn.BatchNorm2d(4000),
nn.ReLU()
)
self.t7 = nn.Sequential(
nn.ConvTranspose2d(in_channels = 512, out_channels = 256, kernel_size =4, stride = 2, padding = 1),
nn.BatchNorm2d(256),
nn.ReLU()
)
self.t8 = nn.Sequential(
nn.ConvTranspose2d(in_channels=256, out_channels=128, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(128),
nn.ReLU()
)
self.t9 = nn.Sequential(
nn.ConvTranspose2d(in_channels=128, out_channels=64, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(64),
nn.ReLU()
)
self.t10 = nn.Sequential(
nn.ConvTranspose2d(in_channels=64, out_channels=3, kernel_size=4, stride=2, padding=1),
nn.Tanh()
)
def forward(self, x):
x = self.t1(x)
x = self.t2(x)
x = self.t3(x)
x = self.t4(x)
x = self.t5(x)
x = self.t6(x)
x = self.t7(x)
x = self.t8(x)
x = self.t9(x)
x = self.t10(x)
return x
model = generatorG()
print(model(torch.randn()).shape)
Discriminator File
import torch
from torch import nn
class DiscriminatorD(nn.Module):
def __init__(self):
super(DiscriminatorD, self).__init__()
self.t1 = nn.Sequential(
nn.Conv2d(in_channels = 3, out_channels = 64, kernel_size =4, stride = 2, padding = 1),
nn.LeakyReLU(0.2, inplace = True)
)
self.t2 = nn.Sequential(
nn.Conv2d(in_channels = 64, out_channels = 128, kernel_size = 4, stride = 2, padding = 1),
nn.BatchNorm2d(128),
nn.LeakyReLU(0.2, inplace = True)
)
self.t3 = nn.Sequential(
nn.Conv2d(in_channels=128, out_channels=256, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(256),
nn.LeakyReLU(0.2, inplace=True)
)
self.t4 = nn.Sequential(
nn.Conv2d(in_channels=256, out_channels=512, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(512),
nn.LeakyReLU(0.2, inplace=True)
)
self.t5 = nn.Sequential(
nn.Conv2d(in_channels=512, out_channels=1, kernel_size=4, stride=1, padding=0),
nn.Sigmoid()
)
def forward(self, x):
x = self.t1(x)
x = self.t2(x)
x = self.t3(x)
x = self.t4(x)
x = self.t5(x)
return x
main.py file
from generator import *
from discriminator import *
import argparse
import os
import random
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.optim as optim
import torch.utils.data
import torchvision.datasets as dset
import torchvision.transforms as transforms
import torchvision.utils as vutils
from torch.autograd import Variable
import utils
epochs = 100
Batch_Size = 64
lr = 0.0002
beta1 = 0.5
over = 4
parser = argparse.ArgumentParser()
parser.add_argument('--dataroot', default = 'dataset/train', help = 'path to dataset')
opt = parser.parse_args()
try:
os.makedirs('result/train/cropped')
os.makedirs('result/train/real')
os.makedirs('result/train/recon')
os.makedirs('model/')
except:
pass
transform = transforms.Compose([transforms.Scale(128),
transforms.CenterCrop(128),
transforms.ToTensor(),
transforms.Normalize((0.5,0.5,0.5), (0.5,0.5,0.5))])
dataset = dset.ImageFolder(root=opt.dataroot, transform= transform)
assert dataset
dataloader = torch.utils.data.DataLoader(dataset, batch_size=Batch_Size, shuffle=True, num_workers=0)
wtl2 = 0.999
def weights_init(m):
classname = m.__class__.__name__
if classname.find('Conv')!=-1:
m.weight.data.normal_(0.0,0.2)
elif classname.find('BatchNorm')!=-1:
m.weight.data.normal_(1.0, 0.02)
m.bias.data.fill_(0)
resume_epoch = 0
netG = generatorG()
netG.apply(weights_init)
netD = DiscriminatorD()
netD.apply(weights_init)
criterion = nn.BCELoss()
criterionMSE = nn.MSELoss()
input_real = torch.FloatTensor(Batch_Size, 3, 128, 128)
input_cropped = torch.FloatTensor(Batch_Size, 3, 128, 128)
label = torch.FloatTensor(Batch_Size)
real_label = 1
fake_label = 0
real_center = torch.FloatTensor(Batch_Size, 3, 64, 64)
input_real = Variable(input_real)
input_cropped = Variable(input_cropped)
label = Variable(label)
real_center = Variable(real_center)
optimizerD = optim.Adam(netD.parameters(), lr = lr, betas=(beta1, 0.999))
optimizerG = optim.Adam(netG.parameters(), lr = lr, betas = (beta1, 0.999))
over = 4
for epoch in range(resume_epoch, epochs):
for i, data in enumerate(dataloader, 0):
real_cpu, _ = data
real_center_cpu = real_cpu[:,:,int(128/4):int(128/4)+int(128/2),int(128/4):int(128/4)+int(128/2)]
batch_size = real_cpu.size(0)
with torch.no_grad():
input_real.resize_(real_cpu.size()).copy_(real_cpu)
input_cropped.resize_(real_cpu.size()).copy_(real_cpu)
real_center.resize_(real_center_cpu.size()).copy_(real_center_cpu)
input_cropped[:, 0, int(128 / 4 + over):int(128 / 4 + 128 / 2 - over),int(128 / 4 + over):int(128 / 4 + 128 / 2 - over)] = 2 * 117.0 / 255.0 - 1.0
input_cropped[:, 1, int(128 / 4 + over):int(128 / 4 + 128 / 2 - over),int(128 / 4 + over):int(128 / 4 + 128 / 2 - over)] = 2 * 104.0 / 255.0 - 1.0
input_cropped[:, 2, int(128 / 4 + over):int(128 / 4 + 128 / 2 - over),int(128 / 4 + over):int(128 / 4 + 128 / 2 - over)] = 2 * 123.0 / 255.0 - 1.0
netD.zero_grad()
with torch.no_grad():
label.resize_(batch_size).fill_(real_label)
output = netD(real_center)
# output = torch.unsqueeze(output[0, 1)
output = torch.squeeze(output, 1)
output = torch.squeeze(output, 1)
output = torch.squeeze(output, 1)
print(output.shape)
# label = label.unsqueeze(1)
# label = label.unsqueeze(1)
# label = label.unsqueeze(1)
print(label.shape)
errD_real = criterion(output, label)
errD_real.backward()
D_x = output.data.mean()
print(input_cropped.shape)
fake = netG(input_cropped)
label.data.fill_(fake_label)
output = netD(fake.detach())
errD_fake = criterion(output, label)
errD_fake.backward()
D_G_z1 = output.data.mean()
errD = errD_real + errD_fake
optimizerD.step()
netG.zero_grad()
label.data.fill_(real_label) # fake labels are real for generator cost
output = netD(fake)
errG_D = criterion(output, label)
wtl2Matrix = real_center.clone()
wtl2Matrix.data.fill_(wtl2 * 10)
wtl2Matrix.data[:, :, int(over):int(128 / 2 - over), int(over):int(128 / 2 - over)] = wtl2
errG_l2 = (fake - real_center).pow(2)
errG_l2 = errG_l2 * wtl2Matrix
errG_l2 = errG_l2.mean()
errG = (1 - wtl2) * errG_D + wtl2 * errG_l2
errG.backward()
D_G_z2 = output.data.mean()
optimizerG.step()
print('[%d / %d][%d / %d] Loss_D: %.4f Loss_G: %.4f / %.4f l_D(x): %.4f l_D(G(z)): %.4f'
% (epoch, epochs, i, len(dataloader),
errD.data, errG_D.data, errG_l2.data, D_x, D_G_z1,))
if i % 100 == 0:
vutils.save_image(real_cpu,
'result/train/real/real_samples_epoch_%03d.png' % (epoch))
vutils.save_image(input_cropped.data,
'result/train/cropped/cropped_samples_epoch_%03d.png' % (epoch))
recon_image = input_cropped.clone()
recon_image.data[:, :, int(128 / 4):int(128 / 4 + 128 / 2), int(128 / 4):int(128 / 4 + 128 / 2)] = fake.data
vutils.save_image(recon_image.data,
'result/train/recon/recon_center_samples_epoch_%03d.png' % (epoch))
utils file
import torch
from PIL import Image
from torch.autograd import Variable
def load_image(filename, size = None, scale = None):
img = Image.open(filename)
if size is not None:
img = img.resize((size, size), Image.ANTIALIAS)
elif scale is not None:
img = img.resize((int(img.size[0]/scale), int(img.size[1]/scale)), Image.ANTIALIAS)
return img
def save_image(filename, data):
img = data.clone().add(1).div(2).mul(255).clamp(0,255).numpy()
img = img.transpose(1,2,0).astype('uint8')
img = Image.fromarray(img)
img.save(filename)
def gram_matrix(y):
(b, ch, h, w) = y.size()
features = y.view(b, ch, w*h)
features_t = features.transpose(1,2)
gram = features.bmm(features_t)/(ch*h*w)
return gram
def normalize_batch(batch):
mean = batch.data.new(batch.data.size())
std = batch.data.new(batch.data.size())
mean[:, 0, :, :] = 0.485
mean[:, 1, :, :] = 0.456
mean[:, 2, :, :] = 0.406
std[:, 0, :, :] = 0.229
std[:, 1, :, :] = 0.224
std[:, 2, :, :] = 0.225
batch = torch.div(batch, 255.0)
batch -= Variable(mean)
# batch /= Variable(std)
batch = torch.div(batch, Variable(std))
return batch
Error message
(impaint_env) vivek#Viveks-MacBook-Pro image_impainter % python main.py
/Users/vivek/DSwork/image_impainter/impaint_env/lib/python3.8/site-packages/torchvision/transforms/transforms.py:310: UserWarning: The use of the transforms.Scale transform is deprecated, please use transforms.Resize instead.
warnings.warn("The use of the transforms.Scale transform is deprecated, " +
torch.Size([7])
torch.Size([7])
torch.Size([7, 3, 128, 128])
Traceback (most recent call last):
File "main.py", line 114, in <module>
fake = netG(input_cropped)
File "/Users/vivek/DSwork/image_impainter/impaint_env/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
return forward_call(*input, **kwargs)
File "/Users/vivek/DSwork/image_impainter/generator.py", line 70, in forward
x = self.t7(x)
File "/Users/vivek/DSwork/image_impainter/impaint_env/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
return forward_call(*input, **kwargs)
File "/Users/vivek/DSwork/image_impainter/impaint_env/lib/python3.8/site-packages/torch/nn/modules/container.py", line 139, in forward
input = module(input)
File "/Users/vivek/DSwork/image_impainter/impaint_env/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
return forward_call(*input, **kwargs)
File "/Users/vivek/DSwork/image_impainter/impaint_env/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 916, in forward
return F.conv_transpose2d(
RuntimeError: Given transposed=1, weight of size [512, 256, 4, 4], expected input[7, 4000, 1, 1] to have 512 channels, but got 4000 channels instead
You have a "gap" between layer t6 and t7 of your generatorG:
# ...
self.t6 = nn.Sequential(
nn.Conv2d(in_channels=512, out_channels=4000, kernel_size=(4, 4)),
nn.BatchNorm2d(4000),
nn.ReLU()
)
self.t7 = nn.Sequential(
nn.ConvTranspose2d(in_channels = 512, out_channels = 256, kernel_size =4, stride = 2, padding = 1),
nn.BatchNorm2d(256),
nn.ReLU()
)
# ...
Your t6 layer expects the input to have 512 channels and outputs a tensor with 4000 channels. However, the next layer, t7, expects the input to have only 512 channels.
You need to adjust either t6 and t7 such that t6 will output exactly the same number of channels t7 is expecting. That is t6's out_channles ,just equal t7's in_channels.

Pytorch DCGAN example for kernel 3

I tried out the pytorch dcgan example and it worked fine but when I tried to change the kernel from 4x4 to 3x3. I only changed the kernel and It gave the following error. Why this error is occurring? To solve this what changes are needed?
ValueError: Using a target size (torch.Size([64])) that is different to the input size (torch.Size([256])) is deprecated. Please ensure they have the same size.
Here is the generator:
class Generator(nn.Module):
def __init__(self, ngpu):
super(Generator, self).__init__()
self.ngpu = ngpu
self.main = nn.Sequential(
# input is Z, going into a convolution
nn.ConvTranspose2d( nz, ngf * 8, kernel_size, 1, 0, bias=False),
nn.BatchNorm2d(ngf * 8),
nn.ReLU(True),
# state size. (ngf*8) x 4 x 4
nn.ConvTranspose2d(ngf * 8, ngf * 4, kernel_size, 2, 1, bias=False),
nn.BatchNorm2d(ngf * 4),
nn.ReLU(True),
# state size. (ngf*4) x 8 x 8
nn.ConvTranspose2d( ngf * 4, ngf * 2, kernel_size, 2, 1, bias=False),
nn.BatchNorm2d(ngf * 2),
nn.ReLU(True),
# state size. (ngf*2) x 16 x 16
nn.ConvTranspose2d( ngf * 2, ngf, kernel_size, 2, 1, bias=False),
nn.BatchNorm2d(ngf),
nn.ReLU(True),
# state size. (ngf) x 32 x 32
nn.ConvTranspose2d( ngf, nc, kernel_size, 2, 1, bias=False),
nn.Tanh()
# state size. (nc) x 64 x 64
)
def forward(self, input):
return self.main(input)
discriminator code:
class Discriminator(nn.Module):
def __init__(self, ngpu):
super(Discriminator, self).__init__()
self.ngpu = ngpu
self.main = nn.Sequential(
# input is (nc) x 64 x 64
nn.Conv2d(nc, ndf, kernel_size, 2, 1, bias=False),
nn.LeakyReLU(0.2, inplace=True),
# state size. (ndf) x 32 x 32
nn.Conv2d(ndf, ndf * 2, kernel_size, 2, 1, bias=False),
nn.BatchNorm2d(ndf * 2),
nn.LeakyReLU(0.2, inplace=True),
# state size. (ndf*2) x 16 x 16
nn.Conv2d(ndf * 2, ndf * 4, kernel_size, 2, 1, bias=False),
nn.BatchNorm2d(ndf * 4),
nn.LeakyReLU(0.2, inplace=True),
# state size. (ndf*4) x 8 x 8
nn.Conv2d(ndf * 4, ndf * 8, kernel_size, 2, 1, bias=False),
nn.BatchNorm2d(ndf * 8),
nn.LeakyReLU(0.2, inplace=True),
# state size. (ndf*8) x 4 x 4
nn.Conv2d(ndf * 8, 1, kernel_size, 1, 0, bias=False),
# 1x1x1
nn.Sigmoid()
)
def forward(self, input):
return self.main(input)
The error showing line is:
In the training loop
# Calculate loss on all-real batch
errD_real = criterion(output, label)
Here criterion = nn.BCELoss()
Whole training loop:
img_list = []
G_losses = []
D_losses = []
iters = 0
# For each epoch
for epoch in range(num_epochs):
# For each batch in the dataloader
for i, data in enumerate(dataloader, 0):
############################
# (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))
###########################
## Train with all-real batch
netD.zero_grad()
# Format batch
real_cpu = data[0].to(device)
#real_cpu = (data.unsqueeze(dim=1).type(torch.FloatTensor)).to(device)
b_size = real_cpu.size(0)
label = torch.full((b_size,), real_label,dtype=torch.float, device=device, )
# Forward pass real batch through D
output = netD(real_cpu).view(-1)
# Calculate loss on all-real batch
errD_real = criterion(output, label)#ERROR
# Calculate gradients for D in backward pass
errD_real.backward()
D_x = output.mean().item()
## Train with all-fake batch
# Generate batch of latent vectors
noise = torch.randn(b_size, nz, 1, 1, device=device)
# Generate fake image batch with G
fake = netG(noise)
label.fill_(fake_label)
# Classify all fake batch with D
output = netD(fake.detach()).view(-1)
# Calculate D's loss on the all-fake batch
errD_fake = criterion(output, label)
# Calculate the gradients for this batch
errD_fake.backward()
D_G_z1 = output.mean().item()
# Add the gradients from the all-real and all-fake batches
errD = errD_real + errD_fake
# Update D
optimizerD.step()
############################
# (2) Update G network: maximize log(D(G(z))) using 'log D' trick
###########################
netG.zero_grad()
label.fill_(real_label) # fake labels are real for generator cost
# Since we just updated D, perform another forward pass of all-fake batch through D
output = netD(fake).view(-1)
# Calculate G's loss based on this output
errG = criterion(output, label)
# Calculate gradients for G
errG.backward()
D_G_z2 = output.mean().item()
# Update G
optimizerG.step()
# Output training stats
if i % 50 == 0:
print('[%d/%d][%d/%d]\tLoss_D: %.4f\tLoss_G: %.4f\tD(x): %.4f\tD(G(z)): %.4f / %.4f'
% (epoch, num_epochs, i, len(dataloader),
errD.item(), errG.item(), D_x, D_G_z1, D_G_z2))
# Save Losses for plotting later
G_losses.append(errG.item())
D_losses.append(errD.item())
# Check how the generator is doing by saving G's output on fixed_noise
if (iters % 500 == 0) or ((epoch == num_epochs-1) and (i == len(dataloader)-1)):
with torch.no_grad():
fake = netG(fixed_noise).detach().cpu()
img_list.append(vutils.make_grid(fake, padding=2, normalize=True))
iters += 1

multiplication of two list using list -erlang

how to multiple two numbers represented in a list for example 123 * 12 = 1476
I want to do this operation using list in this example it should be like this
mul([1,2,3],[1,2]) result will be [1,4,7,6] without converting list to number by using list_to_integer function. I did this so far but its just working if the length of one of the list is equal to one
mul([],A) ->[];
mul(A,[]) ->[];
mul([H|T],B) ->
if
(length([H|T]) ==1) or (length(B)== 1)
->
[X*Y||X<-[H],Y<-B]++mul(T,B);
(length([H|T]) >1) or (length(B) > 1)
->
[X*Y||X<-[H],Y<-B]++mul(T,B)
end.
For example, so:
multi(List, N) when is_number(N) ->
element(1,
lists:foldr(
fun(X, {Sum, Index}) -> {Sum + X * N * pow10(Index), Index + 1} end,
{0, 0}, List));
multi(L1, L2) when is_list(L2) ->
List = [fun() -> multi(L1, X) end() || X <- L2],
element(1,
lists:foldr(
fun(X, {Sum, Index}) -> {Sum + X * pow10(Index), Index + 1} end,
{0, 0}, List)).
pow10(N) when N =:= 0 -> 1;
pow10(N) -> 10 * pow10(N - 1).
If a notice that foldr expressions similar , it is possible to simplify the code:
multi(List, N) when is_number(N) ->
element(1,
lists:foldr(
fun(X, {Sum, Index}) -> {Sum + X * N * pow10(Index), Index + 1} end,
{0, 0}, List));
multi(L1, L2) when is_list(L2) ->
multi([fun() -> multi(L1, X) end() || X <- L2], 1).
pow10(N) when N =:= 0 -> 1;
pow10(N) -> 10 * pow10(N - 1).
for getting list, use integer_to_list:
...
multi(L1, L2) when is_list(L2) ->
create_list(multi([fun() -> multi(L1, X) end() || X <- L2],1)).
create_list(Number)->
[X-48 || X<-integer_to_list(Number)].
...
Here is solution that doesn't use list_to_integer or integer_to_list. Algorithm is called long multiplication and is usually used when language does not support multiplication/sum of big (larger than INT.MAX) numbers. Below is basic implementation that can be optimized in various ways, but will work just fine for education purposes.
Keep in mind that Erlang supports long multiplication and long sum out of the box (as opposed to, say, C), so implementing multiplication is useless in real life applications.
sum(A, B) when is_list(A) andalso is_list(B) ->
lists:reverse(sum_impl(lists:reverse(A), lists:reverse(B), {[], 0})).
mult(A, B) when is_list(A) andalso is_list(B) ->
lists:reverse(mult_impl(lists:reverse(A), lists:reverse(B), {[], []})).
sum_impl([], [], {Res, 0}) -> Res;
sum_impl([], [], {Res, C}) -> sum_impl([C], [0], {Res, 0});
sum_impl(A, [], Acc) -> sum_impl(A, [0], Acc);
sum_impl([], B, Acc) -> sum_impl([0], B, Acc);
sum_impl([HA | TA], [HB | TB], {Res, C}) ->
sum_impl(TA, TB, {Res ++ [(HA + HB + C) rem 10], (HA + HB + C) div 10}).
mult_impl(_A, [], {Res, _C}) -> Res;
mult_impl(A, [HB | TB], {Res, C}) ->
mult_impl(A, TB, {sum_impl(Res, C ++ [X * HB || X <- A], {[], 0}), [0 | C]}).
Here's a version that allows you to specify a base (2-10):
In the shell:
167> c(my).
{ok,my}
168> Base10 = 10.
10
169> Base2 = 2.
2
170> my:list_mult([1,1], [1,1,1], Base10).
[1,2,2,1]
171> 11 * 111.
1221
172> my:list_mult([1,1], [1,1,1], Base2).
[1,0,1,0,1]
173> io:format("~.2B~n", [2#11 * 2#111]).
10101
ok
-module(my).
%%-compile(export_all).
-export([list_mult/3]).
-include_lib("eunit/include/eunit.hrl").
list_mult(List1, List2, Base) ->
Number = digits_to_int(List1, Base) * digits_to_int(List2, Base),
list_of_digits(Number, Base).
list_mult_test() ->
Base10 = 10,
?assertEqual(
list_of_digits(123 * 12, Base10),
list_mult([1,2,3], [1,2], Base10)
),
?assertEqual(
list_of_digits(2 * 5, Base10),
list_mult([2], [5], Base10)
),
?assertEqual(
list_of_digits(0 * 0, Base10),
list_mult([], [], Base10)
),
?assertEqual(
list_of_digits(0 * 23, Base10),
list_mult([], [2,3], Base10)
),
?assertEqual(
list_of_digits(30 * 4, Base10),
list_mult([0,3,0], [0,4], Base10)
),
?assertEqual(
list_of_digits(1 * 3, Base10),
list_mult([0,0,1], [0,3], Base10)
),
Base2 = 2,
?assertEqual(
list_of_digits(2#11 * 2#1000, Base2),
list_mult([1,1], [1,0,0,0], Base2)
),
?assertEqual(
list_of_digits(2#1001 * 2#10, Base2),
list_mult([1,0,0,1], [1,0], Base2)
),
%%Errors:
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([1,3], [1,0,0,0,0], Base2)
),
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([a, 3], [f,1], Base10) %%hex notation
).
%--------------
digits_to_int_test() ->
Base10 = 10,
?assertEqual(
123,
digits_to_int([1,2,3], Base10)
),
?assertEqual(
10,
digits_to_int([1,0], Base10)
),
?assertEqual(
3,
digits_to_int([3], Base10)
),
?assertEqual(
0,
digits_to_int([0], Base10)
),
?assertEqual(
0,
digits_to_int([], Base10)
),
Base2 = 2,
?assertEqual(
2#11,
digits_to_int([1,1], Base2)
),
?assertEqual(
2#1101,
digits_to_int([1,1,0,1], Base2)
),
?assertEqual(
2#11110000,
digits_to_int([1,1,1,1, 0,0,0,0], Base2)
),
?assertEqual(
2#1,
digits_to_int([1], Base2)
),
?assertEqual(
0,
digits_to_int([0], Base2)
),
?assertEqual(
0,
digits_to_int([], Base2)
),
%%Errors:
?assertThrow(
"illegal_number: Some elements are >= to Base",
digits_to_int([1,2,3], Base2)
),
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([a, 3], [f,1], Base10) %%hex notation
).
digits_to_int(List, Base) ->
HighestPower = length(List) - 1,
digits_to_int(List, Base, HighestPower, 0).
digits_to_int([], _, _, Sum) ->
Sum;
digits_to_int([X|Xs], Base, Power, Sum) when X<Base ->
Term = round( math:pow(Base, Power) * X ), %%round() converts float to integer.
digits_to_int(Xs, Base, Power-1, Sum+Term);
digits_to_int(_, _, _, _) ->
throw("illegal_number: Some elements are >= to Base").
%--------------
list_of_digits_test() ->
Base10 = 10,
?assertEqual(
[1,1],
list_of_digits(11, Base10)
),
?assertEqual(
[1,0,0],
list_of_digits(100, Base10)
),
?assertEqual(
[1],
list_of_digits(1, Base10)
),
?assertEqual(
[],
list_of_digits(0, Base10)
),
Base2 = 2,
?assertEqual(
[1,0,1,1],
list_of_digits(2#1011, Base2)
),
?assertEqual(
[1,1,1],
list_of_digits(2#111, Base2)
),
?assertEqual(
[1],
list_of_digits(1, Base2)
).
list_of_digits(0, _Base) ->
[];
list_of_digits(Number, Base) -> %% 193
HighestPower = get_highest_power(Number, Base),
list_of_digits(Number, Base, HighestPower, []).
list_of_digits(Number, _, 0, Digits) ->
lists:reverse([Number|Digits]);
list_of_digits(Number, Base, Power, Digits) ->
X = round(math:pow(Base, Power) ),
Digit = Number div X,
Remainder = Number rem X,
list_of_digits(Remainder, Base, Power-1, [Digit|Digits]).
%---------------
get_highest_power_test() ->
Base10 = 10,
?assertEqual(
2,
get_highest_power(199, Base10)
),
?assertEqual(
3,
get_highest_power(1999, Base10)
),
?assertEqual(
3,
get_highest_power(1000, Base10)
),
?assertEqual(
1,
get_highest_power(19, Base10)
),
?assertEqual(
0,
get_highest_power(5, Base10)
).
get_highest_power(Number, Base) ->
Power = 0,
KeepGoing = (Number div round(math:pow(Base,Power)) ) > 0,
get_highest_power(Number, Base, Power, KeepGoing).
get_highest_power(Number, Base, Power, KeepGoing) when KeepGoing =:= true ->
NewPower = Power+1,
StillKeepGoing = (Number div round(math:pow(Base, NewPower)) ) > 0,
get_highest_power(Number, Base, NewPower, StillKeepGoing);
get_highest_power(_, _, Power, KeepGoing) when KeepGoing =:= false ->
max(0, Power - 1).

How to fix this align environment a bit neater?

I'm writing a description of how recursive functions are applied within lists using the align environment from amsmath in LaTeX. Here's the code:
\begin{align*}
& \reduce (+, 0, & [1, 2, 3, 4]) \\
= & \reduce (+, 0 + 1, & [2, 3, 4]) \\
= & \reduce (+, 0 + 1 + 2, & [3, 4]) \\
= & \reduce (+, 0 + 1 + 2 + 3, & [4]) \\
= & \reduce (+, 0 + 1 + 2 + 3 + 4, & []) \\
= & 0 + 1 + 2 + 3 + 4\\
= & 10
\end{align*}
or my try out to enhance the readability. Inserted \quads there:
\begin{align*}
& \reduce (+,\quad 0, & [1, 2, 3, 4]) \\
=& \reduce (+,\quad 0 + 1, & [2, 3, 4]) \\
=& \reduce (+,\quad 0 + 1 + 2, & [3, 4]) \\
=& \reduce (+,\quad 0 + 1 + 2 + 3, & [4]) \\
=& \reduce (+,\quad 0 + 1 + 2 + 3 + 4, & []) \\
=& 0 + 1 + 2 + 3 + 4\\
=& 10
\end{align*}
It just doesn't look nice. Here's a quick picture of the latter:
http://havu.viuhka.fi/kuvat/alignenv.png
It is almost both readable and aesthetical, but not quite.
How to make the gap smaller? And any other tips you may have are appreciated!
How about using a tabular environment instead of align, with which you can more easily control alignment of the columns? I personally liked the results of:
\begin{tabular}{ r l c }
& reduce(+,\;\, 0, & [1, 2, 3, 4]) \\
=& reduce(+,\;\, 0 + 1, & [2, 3, 4]) \\
=& reduce(+,\;\, 0 + 1 + 2, & [3, 4]) \\
=& reduce(+,\;\, 0 + 1 + 2 + 3, & [4]) \\
=& reduce(+,\;\, 0 + 1 + 2 + 3 + 4, & []) \\
=& 0 + 1 + 2 + 3 + 4\\
=& 10
\end{tabular}
Causes the set on the right to form (visually speaking) an upside down triangle shape. I also replaced \quad with \;\, \quad seemed like too much, and \; not enough... space there.
I briefly considered doing the same to the sums in their own column, but decided that the sums 'growing to the right' was visually more effective.

Resources