1D data Surrogate Gradient Descent in a Convolutional Spiking Neural Network

Aditi_Sharma: <p>I have customized 1d binary datasets classes and then trying to apply surrogate gradient descent spike model and trying it to run the code on cuda, I am not able to implement the data for conv2d so I tried it with conv1d but getting too many errors repeatedly. Looking for Help.</p>
<h1>
<a name="imports-1" class="anchor" href="#imports-1"></a>imports</h1>
<p>import multiprocessing<br>
import csv<br>
import os<br>
import sys</p>
<p>import snntorch as snn<br>
from snntorch import surrogate<br>
from snntorch import backprop<br>
from snntorch import functional as SF<br>
from snntorch import utils<br>
from snntorch import spikeplot as splt</p>
<p>import torch<br>
import torch.nn as nn<br>
import torch.optim as opt<br>
import pytorch_optimizer as optim<br>
from torch.utils.data import DataLoader<br>
import torch.utils.data as IterableDataset<br>
from torchvision import datasets, transforms<br>
import torch.nn.functional as F<br>
from torch.utils.checkpoint import checkpoint</p>
<p>import random<br>
import math</p>
<p>import matplotlib.pyplot as plt<br>
import numpy as np<br>
import itertools</p>
<h1>
<a name="leaky-neuron-model-overriding-the-backward-pass-with-a-custom-function-2" class="anchor" href="#leaky-neuron-model-overriding-the-backward-pass-with-a-custom-function-2"></a>Leaky neuron model, overriding the backward pass with a custom function</h1>
<p>class LeakySigmoidSurrogate(nn.Module):<br>
def <strong>init</strong>(self, beta, threshold=1.0, k=25):<br>
super(Leaky_Surrogate, self).<strong>init</strong>()</p>
<pre><code>    # initialize decay rate beta and threshold
    self.beta = beta
    self.threshold = threshold
    self.surrogate_func = self.FastSigmoid.apply

# the forward function is called each time we call Leaky
def forward(self, input_, mem):
    spk = self.surrogate_func((mem-self.threshold))  # call the Heaviside function
    reset = (spk - self.threshold).detach()
    mem = self.beta * mem + input_ - reset
    return spk, mem

# Forward pass: Heaviside function
# Backward pass: Override Dirac Delta with gradient of fast sigmoid
@staticmethod
class FastSigmoid(torch.autograd.Function):
    @staticmethod
    def forward(ctx, mem, k=25):
        ctx.save_for_backward(mem) # store the membrane potential for use in the backward pass
        ctx.k = k
        out = (mem &gt; 0).float() # Heaviside on the forward pass: Eq(1)
        return out

    @staticmethod
    def backward(ctx, grad_output):
        (mem,) = ctx.saved_tensors  # retrieve membrane potential
        grad_input = grad_output.clone()
        grad = grad_input / (ctx.k * torch.abs(mem) + 1.0) ** 2  # gradient of fast sigmoid on backward pass: Eq(4)
        return grad, None
</code></pre>
<p>spike_grad = surrogate.fast_sigmoid(slope=25)<br>
beta = 0.5</p>
<p>lif1 = snn.Leaky(beta=beta, spike_grad=spike_grad)</p>
<p><span class="hashtag">#crypto</span> Script<br>
net_inputs = 32<br>
net_outputs = 4<br>
net_outputs_offset =28<br>
test_iterations = “Dynamic”<br>
epochs = 10<br>
layers = 6<br>
forward=False<br>
data_input_pth = “./mixcolumns_text.csv”<br>
labels_input_pth = “./mixcolumns_cipher.csv”<br>
num_epochs = 10<br>
test_acc_hist = []<br>
train_files = []<br>
test_files = []</p>
<p>data_input_path = “./split_files_temp”<br>
datafix= ‘mixcolumns_text.csv-’<br>
labelfix= ‘mixcolumns_cipher.csv-’<br>
train_count = 8<br>
test_count = 2<br>
batch_size =100<br>
b_size=100<br>
t_size=10<br>
model=“SKIP”<br>
dataset=“FILE”<br>
activation = “arctan”</p>
<p>if (forward == True):<br>
prefix = ‘Forward’<br>
else:<br>
prefix = ‘Backward’</p>
<p>results_file= f’./{prefix}<em>Rijandel_Mix_Columns</em>{model}-Network_Loading-{dataset}_Trainset-{train_count}_TestSet-{test_count}<em>Evaluation</em>{test_iterations}<em>Outputs-Offset</em>{net_outputs_offset}<em>Outputs</em>{net_outputs}.csv’<br>
model1_filename = f’./{prefix}_Model-Iteration-{model}-Network_Loading-{dataset}_Trainset-{train_count}_Testset-{test_count}<em>Evaluation</em>{test_iterations}<em>Outputs-Offset</em>{net_outputs_offset}<em>Outputs</em>{net_outputs}.csv’</p>
<p>device = torch.device(“cuda:1” if torch.cuda.is_available() else “cpu”)<br>
torch.manual_seed(0)<br>
print(device)</p>
<p>def binary(vector):<br>
zero = torch.Tensor([0.0]).to(device)<br>
one = torch.Tensor([1.0]).to(device)<br>
return torch.where(torch.sigmoidi(vector)&gt;0.5,one,zero)</p>
<p>def binaryC(vector):<br>
zero = torch.Tensor([0.0])<br>
one = torch.Tensor([1.0])<br>
return torch.where(torch.sigmoid(vector)&gt;0.5,one,zero)</p>
<p>class RijiDatasetData(torch.utils.data.Dataset):<br>
<span class="hashtag">#Step</span> 1 when creating a personal Dataset - override <strong>init</strong>()</p>
<h1>
<a name="given-is-a-path-then-prefixes-for-inputs-and-outputs-file-and-a-number-indicating-the-size-of-the-training-and-testing-set-in-files-3" class="anchor" href="#given-is-a-path-then-prefixes-for-inputs-and-outputs-file-and-a-number-indicating-the-size-of-the-training-and-testing-set-in-files-3"></a>given is a path, then prefixes for inputs and outputs file and a number indicating the size of the training and testing set (in files)</h1>
<p><span class="hashtag">#in</span> this case i have shorten data with 100 samples of 511x32 size <span class="hashtag">#torch</span>.size[100,1,32] <span class="hashtag">#each</span> file contains 10000000 samples…<br>
def <strong>init</strong>(self, data_path, datafix, labelfix, number, forward, out_size, out_offsize, test):<br>
self.data_path = data_path<br>
self.output_size = out_size<br>
self.output_offsize = out_offsize<br>
if (forward == True):<br>
self.input = datafix<br>
self.output = labelfix<br>
else:<br>
self.input = labelfix<br>
self.output = datafix<br>
<span class="hashtag">#Initiate</span> the train set from the first 80% of picked up files<br>
rand_array = [100] <span class="hashtag">#random</span>.sample(range(0,430),number)<br>
output_str_array = [str(integer).rjust(6,‘0’) for integer in rand_array]</p>
<pre><code>    input_str_array = [f'{self.data_path}/{self.input}{str(integer).rjust(6,"0")}.txt' for integer in rand_array]
    output_str_array = [f'{self.data_path}/{self.output}{str(integer).rjust(6,"0")}.txt' for integer in rand_array]
    if (test == 1):
        test_files.append(input_str_array)
    else:
        train_files.append(input_str_array)

    print(input_str_array)
    print(output_str_array)
    self.input_data = []
    self.output_data = []
    for path in input_str_array:
        in_file = open(path)
        for l in in_file:
</code></pre>
<p>self.input_data.append(torch.tensor(np.fromstring(l, dtype=float, sep=’ ‘), dtype=torch.float))<br>
for path in output_str_array:<br>
out_file = open(path)<br>
for l in out_file:<br>
self.output_data.append(torch.tensor(np.fromstring(l, dtype=float, sep=’ '), dtype=torch.float))</p>
<pre><code>    self.input_data = torch.stack(self.input_data)
    self.output_data = torch.stack(self.output_data)

def __len__(self):
    return len(self.input_data)

def __getitem__(self,idx):
    input_data = self.input_data[idx]
    output_data = self.output_data[idx][self.output_offsize:self.output_size+self.output_offsize]

    return input_data, output_data
</code></pre>
<p><span class="hashtag">#Do</span> not use for individual bits learning. Works only for the whole dataset and whole width<br>
class RijiDataset(torch.utils.data.IterableDataset):</p>
<pre><code>#Step 1 when creating a personal Dataset - override __init__()
def __init__(self, datafix, labelfix, number, forward, out_size, out_offsize, test):
    self.output_size = out_size
    self.output_offsize = out_offsize
    if (forward == True):
        self.input_path = datafix
        self.outputpath = labelfix
    else:
        self.input_path = labelfix
        self.output_path = datafix
    self.output_size = out_size

def in_line_mapper(self,line):
    lin = line.rstrip("\n")
    v = torch.tensor(np.fromstring(lin, dtype=float, sep=' '), dtype=torch.float)
    return v
def out_line_mapper(self,line):
    lin = line.rstrip("\n")
    v = torch.tensor(np.fromstring(lin, dtype=float, sep=' '), dtype=torch.float)
    return v[self.output_offsize:self.output_size+self.output_offsize]

def __iter__(self):

    input_itr = open(self.input_path)
    output_itr = open(self.output_path)

    mapped_in_itr = map(self.in_line_mapper, input_itr)
    mapped_ou_itr = map(self.out_line_mapper, output_itr)

    zipped_itr = zip(mapped_in_itr,mapped_ou_itr)
    return zipped_itr
</code></pre>
<p><span class="hashtag">#ending</span> dataset from rij1 mixed columns</p>
<p>subset=10</p>
<p>dtype = torch.float<br>
device = torch.device(“cuda”) if torch.cuda.is_available() else torch.device(“cpu”)</p>
<h1>
<a name="define-a-transform-4" class="anchor" href="#define-a-transform-4"></a>Define a transform</h1>
<p>transform = transforms.Compose([<br>
transforms.Resize((28, 28)),<br>
transforms.Grayscale(),<br>
transforms.ToTensor(),<br>
transforms.Normalize((0,), (1,))])</p>
<h1>
<a name="neuron-and-simulation-parameters-5" class="anchor" href="#neuron-and-simulation-parameters-5"></a>neuron and simulation parameters</h1>
<p>spike_grad = surrogate.fast_sigmoid(slope=25)<br>
beta = 0.5<br>
num_steps = 50<br>
lif1 = snn.Leaky(beta=beta, spike_grad=spike_grad)</p>
<pre><code>#construct spike model
</code></pre>
<p>class Net(nn.Module):<br>
def <strong>init</strong>(self, net_inputs, net_outputs):<br>
super(Net,self).<strong>init</strong>()<br>
self.conv1 = nn.Conv1d(100, 1 , 3)<br>
self.lif1 = snn.Leaky(beta=beta, spike_grad=spike_grad)<br>
self.conv1 = nn.Conv1d(1, 100, 3)<br>
self.lift2 = snn.Leaky(beta=beta, spike_grad=spike_grad)<br>
self.fc1 = nn.Linear(28, 100)<br>
self.lif3 = snn.Leaky(beta=beta, spike_grad=spike_grad)</p>
<pre><code>def forward(self, x):
    mem1 = self.lift1.init_leaky()
    mem2 = self.lift2.init_leaky()
    mem3 = self.lift3.init_leaky()
    

    spk3_rec = []
    mem3_rec = []

    for step in range(num_steps):
        cur1 = F.max_pool2d(self.conv1(x), 2)
        spk1,mem1 = self.lif1(cur1, mem1)
        cur2 = F.max_pool2d(self.conv2(spk1), 2)
        spk2,mem2 = self.lif2(cur2,mem2)
        cur3 = self.fc1(spk2.view(batch_size, -1))
        spk3,mem3 = self.lif3(cur3, mem3)

        spk3_rec.append(spk3)
        mem3_rec.append(mem3)

    return torch.stack(spk3_rec) , torch.stack(mem3_rec)
</code></pre>
<p>f (model == “SKIP”):<br>
Mmodel = Net(net_inputs,net_outputs).to(device)<br>
elif (model == “FC”):<br>
Mmodel = CModel(net_inputs,net_outputs).to(device)<br>
elif (model == “CONV”):<br>
Mmodel = ConvModel(net_inputs,net_outputs).to(device)</p>
<p><span class="hashtag">#criterion1</span> = nn.MSELoss()<br>
criterion1 = nn.BCEWithLogitsLoss()<br>
<span class="hashtag">#optimizer1</span> = optim.Ranger(Mmodel.parameters(), lr=0.001,alpha=0.5, k=6,betas=(0.95, 0.999), eps=1e-08, weight_decay=0)<br>
<span class="hashtag">#optimizer1</span> = optim.Ranger21(Mmodel.parameters(), lr=0.01,alpha=0.5, k=6,betas=(0.95, 0.999), eps=1e-08, weight_decay=0, N_sma_threshold=5)<br>
optimizer1 = torch.optim.Adam(Mmodel.parameters(), lr=1e-2, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)<br>
#<span class="hashtag">#optimizer</span> = torch.optim.Adam(net.parameters(), lr=1e-2, betas=(0.9, 0.999))<br>
if (dataset == “FILE”):<br>
train_dataset = RijiDatasetData(data_input_path,datafix, labelfix, train_count, forward, net_outputs, net_outputs_offset, test=0)<br>
dataloader = DataLoader(train_dataset, batch_size=b_size, num_workers=8, shuffle=True)<br>
elif(dataset == “POINTER”):<br>
train_dataset = RijiDataset(data_input_pth, labels_input_pth, train_count, forward, net_outputs, net_outputs_offset, test=0, transform=transform)<br>
<span class="hashtag">#train_dataloader</span> = DataLoader(train_dataset, batch_size=b_size, num_workers=8)<br>
dataloader = DataLoader(train_dataset, batch_size=b_size, num_workers=8)</p>
<p>if (test_iterations == “Static” ):<br>
test_dataset = RijiDatasetData(data_input_path,datafix, labelfix, test_count, forward, net_outputs, net_outputs_offset, test=1, transform=transform)<br>
<span class="hashtag">#test_dataloader</span> = DataLoader(test_dataset, batch_size=b_size, num_workers=8)</p>
<h1>
<a name="initialize-network-6" class="anchor" href="#initialize-network-6"></a>Initialize Network</h1>
<p>net = nn.Sequential(nn.Conv1d(100, 1 , 3),<br>
nn.MaxPool1d(1),<br>
snn.Leaky(beta=beta, spike_grad=spike_grad, init_hidden=True),<br>
nn.Conv1d(1, 100, 3),<br>
nn.MaxPool1d(1),<br>
snn.Leaky(beta=beta, spike_grad=spike_grad, init_hidden=True),<br>
nn.Flatten(),<br>
nn.Linear(28,100),<br>
snn.Leaky(beta=beta, spike_grad=spike_grad, init_hidden=True, output=True)<br>
).to(device)</p>
<p>X, y = next(iter(dataloader))<br>
X = X.to(device)<br>
y = y.to(device)</p>
<p>for step in range(num_steps):<br>
<span class="hashtag">#for</span> X, y in dataloader:<br>
<span class="hashtag">#X</span> = torch.unsqueeze(X,dim=1).to(device)<br>
print(X.shape)<br>
print(y.shape)<br>
spk_out, mem_out = net(X)<br>
<span class="hashtag">#mem_out</span> = net(X)</p>
<p>def forward_pass(net, num_steps, X):<br>
mem_rec = []<br>
spk_rec = []<br>
utils.reset(net)  # resets hidden states for all LIF neurons in net</p>
<pre><code>for step in range(num_steps):
#for X, y in dataloader:
    #X = torch.unsqueeze(X,dim=1).to(device)
    print(X.shape)
    #spk_out = net(X)
    #mem_out = net(X)
    spk_out, mem_out = net(X)
    spk_rec.append(spk_out)
    mem_rec.append(mem_out)

return torch.stack(spk_rec) , torch.stack(mem_rec)
</code></pre>
<p>spk_rec, mem_rec = forward_pass(net, num_steps, X)<br>
<span class="hashtag">#spk_rec</span> = forward_pass(net, num_steps, X)</p>
<p>results1 = np.zeros([epochs,net_outputs+4])<br>
running_loss1 = 0<br>
running_loss2 = 0</p>
<p>max_accuracy = 0<br>
target_0_1 = torch.zeros([1,net_outputs])<br>
output_0_1 = torch.zeros([1,net_outputs])<br>
for t in range(epochs):<br>
Mmodel.train()<br>
correct0 = 0.0<br>
total0 = 0.0<br>
for X, y in dataloader:</p>
<pre><code>    #        X = torch.unsqueeze(X,dim=1).to(device)
#For CNN
    #X,y = torch.unsqueeze(X,dim=1).to(device), torch.unsqueeze(y,dim=1).to(device)
    #X,y = torch.squeeze(X,dim=1).to(device), torch.squeeze(y,dim=1).to(device)
    spk_out, mem_out = net(X)
    #spk_rec.append(spk_out)
    #mem_rec.append(mem_out)
    #out = Mmodel(X)
</code></pre>
<p><span class="hashtag">#For</span> CNN<br>
#<span class="hashtag">#loss1</span> = criterion1(torch.unsqueeze(out,dim=1),y)<br>
<span class="hashtag">#loss1</span> = criterion1(torch.squeeze(out,dim=1),y)<br>
##<span class="hashtag">#loss1</span> = criterion1(out,y)<br>
# already imported snntorch.functional as SF<br>
loss_fn = SF.ce_rate_loss()<br>
loss_val = loss_fn(spk_rec, X)<br>
optimizer1.zero_grad()<br>
loss1.backward()<br>
optimizer1.step()<br>
running_loss1 += loss1.item()<br>
<span class="hashtag">#learning</span> accuracy<br>
outs, ys = out.to(device), y.to(device)<br>
total0 += ys.size(0)<br>
outs = binaryC(outs)<br>
target_0_1 += torch.sum(ys, dim=0)<br>
output_0_1 = torch.sum(outs, dim=0)<br>
correct0 += ((outs == ys).sum().item())/(ys.size(2))</p>
<pre><code>print(f"The loss from an untrained network is {loss_val.item():.3f}")
acc = SF.accuracy_rate(spk_rec, net_outputs)
print(f"The accuracy of a single batch using an untrained network is {acc*100:.3f}%")
print('[%d] loss: %.5f and accuracy %.5f ' %(t + 1, running_loss1, 100*correct0/total0))
if (running_loss1/1000 == 0.0 or running_loss1 == running_loss2):
    break
results1[t][0] = t
results1[t][1] = running_loss1
results1[t][2] = 100* correct0/total0
results1[t][3:3+net_outputs] = target_0_1/total0

running_loss2 = running_loss1
running_loss1 = 0.0


Mmodel.eval()
correct1 = 0.0
total = 0.0
if (test_iterations == "Static" ):
    dataloader = DataLoader(test_dataset, batch_size=t_size, num_workers=8, shuffle=False)
elif (test_iterations == "Dynamic" ):
    test_dataset = RijiDatasetData(data_input_path,datafix, labelfix, test_count, forward, net_outputs, net_outputs_offset, test=1)
    dataloader = DataLoader(test_dataset, batch_size=t_size, num_workers=8, shuffle=False)
else:
    dataloader = DataLoader(train_dataset, batch_size=t_size, num_workers=8)
    with torch.no_grad():
        for X, y in dataloader:
            X,y = torch.unsqueeze(X,dim=1).to(device), torch.unsqueeze(y,dim=1).to(device)
</code></pre>
<p>outputs1 = Mmodel(X)<br>
oututs, ys = outputs1.to(device), y.to(device)<br>
total += ys.size(0)<br>
outs = binaryC(oututs)<br>
correct1 += ((outs == ys).sum().item())/(ys.size(2))</p>
<pre><code>print('Accuracy of the network on the {} test images: {} '.format(total, (100*correct1 / total)))
results1[t][net_outputs+3] = 100* correct1/total
if (results1[t][3] &gt; max_accuracy):
    max_accuracy = results1[t][3]
    torch.save(Mmodel.state_dict(), model1_filename)
if (results1[t][net_outputs+3] == 100):
    break
</code></pre>
<h2>
<a name="with-openresults_file-w-as-csvfile-7" class="anchor" href="#with-openresults_file-w-as-csvfile-7"></a>with open(results_file, ‘w’) as csvfile:</h2>
<pre><code>##spamwriter = csv.writer(csvfile, delimiter=' ')  
##spamwriter.writerow(train_files)                                                                                                       spamwriter.writerow(test_files)                                                                                                        spamwriter.writerows(results1)
</code></pre>
<p>def batch_accuracy(train_dataloader, net, num_steps):<br>
with torch.no_grad():<br>
total = 0<br>
acc = 0<br>
net.eval()</p>
<pre><code>    train_dataloader = iter(train_dataloader)
    for Mmodel in train_loader:
        ConvModel(net_inputs,net_outputs).to(device)
        spk_rec, _ = forward_pass(net, num_steps, net_input)

        acc += SF.accuracy_rate(spk_rec, Mmodel = ConvModel(net_inputs,net_outputs).to(device)) * spk_rec.size(1)
        total += spk_rec.size(1)

return acc/total
</code></pre>
<p>test_acc = batch_accuracy(test_dataloader, net, num_steps)</p>
<p>print(f"The total accuracy on the test set is: {test_acc * 100:.2f}%")<br>
for epoch in range(num_epochs):</p>
<pre><code>avg_loss = backprop.BPTT(net, train_dataloader, optimizer=optimizer, criterion=loss_fn,
                        num_steps=num_steps, time_var=False, device=device)

print(f"Epoch {epoch}, Train Loss: {avg_loss.item():.2f}")

# Test set accuracy
test_acc = batch_accuracy(train_dataloader, net, num_steps)
test_acc_hist.append(test_acc)

print(f"Epoch {epoch}, Test Acc: {test_acc * 100:.2f}%\n")
</code></pre>
<h1>
<a name="plot-loss-8" class="anchor" href="#plot-loss-8"></a>Plot Loss</h1>
<p>fig = plt.figure(facecolor=“w”)<br>
plt.plot(test_acc_hist)<br>
plt.title(“Test Set Accuracy”)<br>
plt.xlabel(“Epoch”)<br>
plt.ylabel(“Accuracy”)<br>
plt.show()</p>
<p>spk_rec, mem_rec = forward_pass(net, num_steps, net_inputs)</p>
<p>from IPython.display import HTML</p>
<p>idx = 0</p>
<p>fig, ax = plt.subplots(facecolor=‘w’, figsize=(12, 7))<br>
labels=[‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’,‘9’]<br>
print(f"The target label is: {net_outputs[idx]}")</p>
<p>plt.rcParams[‘animation.ffmpeg_path’] = ‘C:\path\to\your\ffmpeg.exe’</p>
<h1>
<a name="plot-spike-count-histogram-9" class="anchor" href="#plot-spike-count-histogram-9"></a>Plot spike count histogram</h1>
<p>anim = splt.spike_count(spk_rec[:, idx].detach().cpu(), fig, ax, labels=labels,<br>
animate=True, interpolate=4)</p>
<p>HTML(anim.to_html5_video())<br>
anim.save(“spike_bar.mp4”)</p>
<p>with open(results_file, ‘w’) as csvfile:<br>
spamwriter = csv.writer(csvfile, delimiter=’ ')<br>
spamwriter.writerow(train_files)<br>
spamwriter.writerow(test_files)<br>
spamwriter.writerows(results1)</p>
<p>error message</p>
<p>Traceback (most recent call last):<br>
File “/raid/rijndael-mixcolumns/spike1.py”, line 447, in <br>
spk_rec, mem_rec = forward_pass(net, num_steps, X)<br>
File “/raid/rijndael-mixcolumns/spike1.py”, line 441, in forward_pass<br>
spk_out, mem_out = net(X)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl<br>
return forward_call(*input, **kwargs)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/container.py”, line 139, in forward<br>
input = module(input)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl<br>
return forward_call(*input, **kwargs)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/conv.py”, line 307, in forward<br>
return self._conv_forward(input, self.weight, self.bias)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/conv.py”, line 303, in _conv_forward<br>
return F.conv1d(input, weight, bias, self.stride,<br>
RuntimeError: Given groups=1, weight of size [1, 100, 1], expected input[100, 1, 32] to have 100 channels, but got 1 channels instead</p>
<p>error<br>
cuda:1<br>
cuda<br>
[‘./split_files_temp/mixcolumns_cipher.csv-000100.txt’]<br>
[‘./split_files_temp/mixcolumns_text.csv-000100.txt’]<br>
torch.Size([100, 32])<br>
torch.Size([100, 4])<br>
Traceback (most recent call last):<br>
File “/raid/rijndael-mixcolumns/spike1.py”, line 426, in <br>
spk_out, mem_out = net(X)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl<br>
return forward_call(*input, **kwargs)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/container.py”, line 139, in forward<br>
input = module(input)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/module.py”, line 1130, in _call_impl<br>
return forward_call(*input, **kwargs)<br>
File “/raid/rijndael-mixcolumns/envs/pytorch/lib/python3.9/site-packages/torch/nn/modules/linear.py”, line 114, in forward<br>
return F.linear(input, self.weight, self.bias)<br>
RuntimeError: mat1 and mat2 shapes cannot be multiplied (100x32 and 100x32)</p>