BrokenPipeError: [Errno 32] Broken pipe on Windows and CUDA 10

I am able to run my program on system with CUDA 9.2, Quadro M5000 (5), and python 3.7.0 (anaconda) while the same program giving me an error on another system with the CUDA 10.0, GeForce GTX 1080 Ti (6), and python 3.7.1

 ForkingPickler(file, protocol).dump(obj)

BrokenPipeError: [Errno 32] Broken pipe

the whole code wrap in a function named train_valid_model() and just add the main guard in the script:

def train_valid_model():
    # complete code here

if __name__=='__main__':
    train_valid_model()

In Anaconda Prompt to make sure about is CUDA available I’ve done this import torch torch.cuda.is_available() and it’s returning True while it’s not able to do this t_image = t_image.to(device)

It only works when num_workers=0 and if I set it to 1 or 2 I will get this error. Any idea why I am getting this error while the program is same just the CUDA version and python version are different?

Which pytorch version is this?

@SimonW It’s Torch version: 1.0.0

I also tried with the cuda 9.2 and I am getting the same error.

Any update on this issue?
I am experiencing similar problem. Below whole error stack.


(pytorch) C:\Users\dzidu\Documents\Python Scripts\pytorch-cifar-master>python main.py
==> Preparing data..
Files already downloaded and verified
Files already downloaded and verified
==> Building model..

Epoch: 0
==> Preparing data..
Files already downloaded and verified
Files already downloaded and verified
==> Building model..

Epoch: 0
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\spawn.py", line 105, in spawn_main
    exitcode = _main(fd)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\spawn.py", line 114, in _main
    prepare(preparation_data)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\spawn.py", line 225, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\spawn.py", line 277, in _fixup_main_from_path
    run_name="__mp_main__")
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\dzidu\Documents\Python Scripts\pytorch-cifar-master\main.py", line 142, in <module>
    train(epoch)
  File "C:\Users\dzidu\Documents\Python Scripts\pytorch-cifar-master\main.py", line 90, in train
    for batch_idx, (inputs, targets) in enumerate(trainloader):
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\site-packages\torch\utils\data\dataloader.py", line 193, in __iter__
    return _DataLoaderIter(self)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\site-packages\torch\utils\data\dataloader.py", line 469, in __init__
    w.start()
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\process.py", line 105, in start
    self._popen = self._Popen(self)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\context.py", line 322, in _Popen
    return Popen(process_obj)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\popen_spawn_win32.py", line 33, in __init__
    prep_data = spawn.get_preparation_data(process_obj._name)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\spawn.py", line 143, in get_preparation_data
    _check_not_importing_main()
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\spawn.py", line 136, in _check_not_importing_main
    is not going to be frozen to produce an executable.''')
RuntimeError:
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.
Traceback (most recent call last):
  File "main.py", line 142, in <module>
    train(epoch)
  File "main.py", line 90, in train
    for batch_idx, (inputs, targets) in enumerate(trainloader):
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\site-packages\torch\utils\data\dataloader.py", line 193, in __iter__
    return _DataLoaderIter(self)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\site-packages\torch\utils\data\dataloader.py", line 469, in __init__
    w.start()
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\process.py", line 105, in start
    self._popen = self._Popen(self)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\context.py", line 322, in _Popen
    return Popen(process_obj)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Users\dzidu\Anaconda3\envs\pytorch\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
BrokenPipeError: [Errno 32] Broken pipe

Thanks for any info.

system info:

Microsoft Windows [Version 10.0.17134.706]
(c) 2018 Microsoft Corporation. All rights reserved.

PyTorch:

>>> torch.cuda.is_available()
True
>>> torch.__version__
'1.1.0'

Thanks for any update on this.

Did you add the if-clause protection to your script?
This is necessary if you are using Windows and multiple workers in your DataLoader:

def main():
   # your code

if __name__ == '__main__':
    main()
1 Like

Of course I didn’t and that is why it didn’t work ;).

Thanks for that, now it works!

I use if-clause to protect my dataloader and training process, but it still told me “[Errno 32] Broken pipe”. Please tell me how to solve it.

Try to use num_workers=0 and rerun the code.
If your Dataset raises errors, the multiple processes of the DataLoader might crash without giving you a good error message.

Thanks a lot. I use num_workers=0 and it works. Maybe my Dataset has some problem, I will check it later.

Dear Sir, I got the error"File “C:\Users\max\anaconda3\lib\multiprocessing\reduction.py”, line 60, in dump ForkingPickler(file, protocol).dump(obj)
BrokenPipeError: [Errno 32] Broken pipe. not i use win7 what the modifications that should i made here my codes

import os
import itertools
import time
import random

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import seaborn as sns
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torch.optim import AdamW
from torch.optim.lr_scheduler import (CosineAnnealingLR,
CosineAnnealingWarmRestarts,
StepLR,
ExponentialLR)

from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.metrics import accuracy_score, auc, f1_score, precision_score, recall_score
class Config:
csv_path = ‘’
seed = 2021
device = ‘cuda:0’ if torch.cuda.is_available() else ‘cpu’
attn_state_path = ‘C:/Users/max/iinput/mitbih-with-synthetic/attn.pth’
lstm_state_path = ‘C:/Users/max/input/mitbih-with-synthetic/lstm.pth’
cnn_state_path = ‘C:/Users/max/iinput/mitbih-with-synthetic/cnn.pth’

attn_logs = 'C:/Users/max/iinput/mitbih-with-synthetic/attn.csv'
lstm_logs = 'C:/Users/max/iinput/mitbih-with-synthetic/lstm.csv'
cnn_logs = 'C:/Users/max/iinput/mitbih-with-synthetic/cnn.csv'

train_csv_path = 'C:/Users/max/iinput/mitbih_with_syntetic_train.csv'
test_csv_path = 'C:/Users/max/iinput/mitbih_with_syntetic_test.csv'

def seed_everything(seed: int):
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed(seed)
config = Config()
seed_everything(config.seed)
df_ptbdb = pd.read_csv(‘C:/Users/max/iinput/ptbdb_abnormal.csv’)
df_mitbih = pd.read_csv(‘C:/Users/max/iinput/mitbih_train.csv’)
df_ptbdb
df_mitbih_train = pd.read_csv(‘C:/Users/max/iinput/mitbih_train.csv’, header=None)
df_mitbih_test = pd.read_csv(‘C:/Users/max/iinput/mitbih_test.csv’, header=None)
df_mitbih = pd.concat([df_mitbih_train, df_mitbih_test], axis=0)
df_mitbih.rename(columns={187: ‘class’}, inplace=True)

id_to_label = {
0: “Normal”,
1: “Artial Premature”,
2: “Premature ventricular contraction”,
3: “Fusion of ventricular and normal”,
4: “Fusion of paced and normal”
}
df_mitbih[‘label’] = df_mitbih.iloc[:, -1].map(id_to_label)
print(df_mitbih.info())
df_mitbih.to_csv(‘data.csv’, index=False)
config.csv_path = ‘data.csv’
df_mitbih = pd.read_csv(config.csv_path)
df_mitbih[‘label’].value_counts()
percentages = [count / df_mitbih.shape[0] * 100 for count in df_mitbih[‘label’].value_counts()]

fig, ax = plt.subplots(figsize=(12, 6))
sns.countplot(
x=df_mitbih[‘label’],
ax=ax,
palette=“bright”,
order=df_mitbih[‘label’].value_counts().index
)
ax.set_xticklabels(ax.get_xticklabels(), rotation=15);

for percentage, count, p in zip(
percentages,
df_mitbih[‘label’].value_counts(sort=True).values,
ax.patches):
percentage = f’{np.round(percentage, 2)}%’
x = p.get_x() + p.get_width() / 2 - 0.4
y = p.get_y() + p.get_height()
ax.annotate(str(percentage)+" / "+str(count), (x, y), fontsize=12, fontweight=‘bold’)

plt.savefig(‘data_dist.png’, facecolor=‘w’, edgecolor=‘w’, format=‘png’,
transparent=False, bbox_inches=‘tight’, pad_inches=0.1)
plt.savefig(‘data_dist.svg’, facecolor=‘w’, edgecolor=‘w’, format=‘svg’,
transparent=False, bbox_inches=‘tight’, pad_inches=0.1)
config.csv_path = ‘C:/Users/max/iinput/mitbih_with_syntetic.csv’
df_mitbih_new = pd.read_csv(config.csv_path)
percentages1 = [count / df_mitbih.shape[0] * 100 for count in df_mitbih[‘label’].value_counts()]
percentages2 = [count / df_mitbih_new.shape[0] * 100 for count in df_mitbih_new[‘label’].value_counts()]

fig, axs = plt.subplots(1,2, figsize=(18, 4))

origin

sns.countplot(
x=df_mitbih[‘label’],
ax=axs[0],
palette=“bright”,
order=df_mitbih[‘label’].value_counts().index
)
axs[0].set_xticklabels(axs[0].get_xticklabels(), rotation=15);
axs[0].set_title(“Before”, fontsize=15)
for percentage, count, p in zip(
percentages1,
df_mitbih[‘label’].value_counts(sort=True).values,
axs[0].patches):

percentage = f'{np.round(percentage, 2)}%'
x = p.get_x() + p.get_width() / 2 - 0.4
y = p.get_y() + p.get_height()
axs[0].annotate(str(percentage)+" / "+str(count), (x, y), fontsize=10, fontweight='bold')

with synthetic

sns.countplot(
x=df_mitbih_new[‘label’],
ax=axs[1],
palette=“bright”,
order=df_mitbih_new[‘label’].value_counts().index
)
axs[1].set_xticklabels(axs[1].get_xticklabels(), rotation=15);
axs[1].set_title(“After”, fontsize=15)
for percentage, count, p in zip(
percentages2,
df_mitbih_new[‘label’].value_counts(sort=True).values,
axs[1].patches):

percentage = f'{np.round(percentage, 2)}%'
x = p.get_x() + p.get_width() / 2 - 0.4
y = p.get_y() + p.get_height()
axs[1].annotate(str(percentage)+" / "+str(count), (x, y), fontsize=10, fontweight='bold')

#plt.suptitle(“Balanced Sampling between classes”, fontsize=20, weight=“bold”, y=1.01)
plt.savefig(‘data_dist.png’, facecolor=‘w’, edgecolor=‘w’, format=‘png’,
transparent=False, bbox_inches=‘tight’, pad_inches=0.1)
plt.savefig(‘data_dist.svg’, facecolor=‘w’, edgecolor=‘w’, format=‘svg’,
transparent=False, bbox_inches=‘tight’, pad_inches=0.1)
N = 5
samples = [df_mitbih.loc[df_mitbih[‘class’] == cls].sample(N) for cls in range(N)]
titles = [id_to_label[cls] for cls in range(5)]

with plt.style.context(“seaborn-white”):
fig, axs = plt.subplots(3, 2, figsize=(20, 7))
for i in range(5):
ax = axs.flat[i]
ax.plot(samples[i].values[:,:-2].transpose())
ax.set_title(titles[i])
#plt.ylabel(“Amplitude”)

plt.tight_layout()
plt.suptitle("ECG Signals", fontsize=20, y=1.05, weight="bold")
plt.savefig(f"signals_per_class.svg",
                format="svg",bbox_inches='tight', pad_inches=0.2)
plt.savefig(f"signals_per_class.png", 
                format="png",bbox_inches='tight', pad_inches=0.2)
#%time

signals = [’ '.join(df_mitbih.iloc[i, :-1].apply(str).values) for i in range(df_mitbih.shape[0])]
y = df_mitbih.iloc[:, -1].values.tolist()
print(len(signals), len(y))

print(f’data has {len(set([sig for line in signals for sig in line.split()]))} out of 16 372 411 unique values.’)
class ECGDataset(Dataset):

def __init__(self, df):
    self.df = df
    self.data_columns = self.df.columns[:-2].tolist()

def __getitem__(self, idx):
    signal = self.df.loc[idx, self.data_columns].astype('float32')
    signal = torch.FloatTensor([signal.values])                 
    target = torch.LongTensor(np.array(self.df.loc[idx, 'class']))
    return signal, target

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

def get_dataloader(phase: str, batch_size: int = 96) → DataLoader:
‘’’
Dataset and DataLoader.
Parameters:
pahse: training or validation phase.
batch_size: data per iteration.
Returns:
data generator
‘’’
df = pd.read_csv(config.train_csv_path)
train_df, val_df = train_test_split(
df, test_size=0.15, random_state=config.seed, stratify=df[‘label’]
)
train_df, val_df = train_df.reset_index(drop=True), val_df.reset_index(drop=True)
df = train_df if phase == ‘train’ else val_df
dataset = ECGDataset(df)
dataloader = DataLoader(dataset=dataset, batch_size=batch_size, num_workers=4)
return dataloader
class Swish(nn.Module):
def forward(self, x):
return x * torch.sigmoid(x)

x = torch.linspace(-10.0, 10.0, 100)
swish = Swish()
swish_out = swish(x)
relu_out = torch.relu(x)

plt.title(‘Swish function’)
plt.plot(x.numpy(), swish_out.numpy(), label=‘Swish’)
plt.plot(x.numpy(), relu_out.numpy(), label=‘ReLU’)
plt.legend();
plt.show()
class ConvNormPool(nn.Module):
“”“Conv Skip-connection module”""
def init(
self,
input_size,
hidden_size,
kernel_size,
norm_type=‘bachnorm’
):
super().init()

    self.kernel_size = kernel_size
    self.conv_1 = nn.Conv1d(
        in_channels=input_size,
        out_channels=hidden_size,
        kernel_size=kernel_size
    )
    self.conv_2 = nn.Conv1d(
        in_channels=hidden_size,
        out_channels=hidden_size,
        kernel_size=kernel_size
    )
    self.conv_3 = nn.Conv1d(
        in_channels=hidden_size,
        out_channels=hidden_size,
        kernel_size=kernel_size
    )
    self.swish_1 = Swish()
    self.swish_2 = Swish()
    self.swish_3 = Swish()
    if norm_type == 'group':
        self.normalization_1 = nn.GroupNorm(
            num_groups=8,
            num_channels=hidden_size
        )
        self.normalization_2 = nn.GroupNorm(
            num_groups=8,
            num_channels=hidden_size
        )
        self.normalization_3 = nn.GroupNorm(
            num_groups=8,
            num_channels=hidden_size
        )
    else:
        self.normalization_1 = nn.BatchNorm1d(num_features=hidden_size)
        self.normalization_2 = nn.BatchNorm1d(num_features=hidden_size)
        self.normalization_3 = nn.BatchNorm1d(num_features=hidden_size)
        
    self.pool = nn.MaxPool1d(kernel_size=2)
def forward(self, input):
    conv1 = self.conv_1(input)
    x = self.normalization_1(conv1)
    x= self.swish_1(x)
    x = F.pad(x, pad=(self.kernel_size - 1, 0))
    
    x = self.conv_2(x)
    x = self.normalization_2(x)
    x = self.swish_2(x)
    x = F.pad(x, pad=(self.kernel_size - 1, 0))
    
    conv3 = self.conv_3(x)
    x = self.normalization_3(conv1+conv3)
    x = self.swish_3(x)
    x = F.pad(x, pad=(self.kernel_size - 1, 0))   
    
    x = self.pool(x)
    return x

class CNN(nn.Module):
def init(
self,
input_size = 1,
hid_size = 256,
kernel_size = 5,
num_classes = 5,
):

    super().__init__()
    
    self.conv1 = ConvNormPool(
        input_size=input_size,
        hidden_size=hid_size,
        kernel_size=kernel_size,
    )
    self.conv2 = ConvNormPool(
        input_size=hid_size,
        hidden_size=hid_size//2,
        kernel_size=kernel_size,
    )
    self.conv3 = ConvNormPool(
        input_size=hid_size//2,
        hidden_size=hid_size//4,
        kernel_size=kernel_size,
    )
    self.avgpool = nn.AdaptiveAvgPool1d((1))
    self.fc = nn.Linear(in_features=hid_size//4, out_features=num_classes)
    
def forward(self, input):
    x = self.conv1(input)
    x = self.conv2(x)
    x = self.conv3(x)
    x = self.avgpool(x)        
    # print(x.shape) # num_features * num_channels
    x = x.view(-1, x.size(1) * x.size(2))
    x = F.softmax(self.fc(x), dim=1)
    return x

class RNN(nn.Module):
“”“RNN module(cell type lstm or gru)”""
def init(
self,
input_size,
hid_size,
num_rnn_layers=1,
dropout_p = 0.2,
bidirectional = False,
rnn_type = ‘lstm’,
):
super().init()

    if rnn_type == 'lstm':
        self.rnn_layer = nn.LSTM(
            input_size=input_size,
            hidden_size=hid_size,
            num_layers=num_rnn_layers,
            dropout=dropout_p if num_rnn_layers>1 else 0,
            bidirectional=bidirectional,
            batch_first=True,
        )
    else:
        self.rnn_layer = nn.GRU(
            input_size=input_size,
            hidden_size=hid_size,
            num_layers=num_rnn_layers,
            dropout=dropout_p if num_rnn_layers>1 else 0,
            bidirectional=bidirectional,
            batch_first=True,
        )
def forward(self, input):
    outputs, hidden_states = self.rnn_layer(input)
    return outputs, hidden_states

class RNNModel(nn.Module):
def init(
self,
input_size,
hid_size,
rnn_type,
bidirectional,
n_classes=5,
kernel_size=5,
):
super().init()

    self.rnn_layer = RNN(
        input_size=46,#hid_size * 2 if bidirectional else hid_size,
        hid_size=hid_size,
        rnn_type=rnn_type,
        bidirectional=bidirectional
    )
    self.conv1 = ConvNormPool(
        input_size=input_size,
        hidden_size=hid_size,
        kernel_size=kernel_size,
    )
    self.conv2 = ConvNormPool(
        input_size=hid_size,
        hidden_size=hid_size,
        kernel_size=kernel_size,
    )
    self.avgpool = nn.AdaptiveAvgPool1d((1))
    self.fc = nn.Linear(in_features=hid_size, out_features=n_classes)
def forward(self, input):
    x = self.conv1(input)
    x = self.conv2(x)
    x, _ = self.rnn_layer(x)
    x = self.avgpool(x)
    x = x.view(-1, x.size(1) * x.size(2))
    x = F.softmax(self.fc(x), dim=1)#.squeeze(1)
    return x

class RNNAttentionModel(nn.Module):
def init(
self,
input_size,
hid_size,
rnn_type,
bidirectional,
n_classes=5,
kernel_size=5,
):
super().init()
self.rnn_layer = RNN(
input_size=46,
hid_size=hid_size,
rnn_type=rnn_type,
bidirectional=bidirectional
)
self.conv1 = ConvNormPool(
input_size=input_size,
hidden_size=hid_size,
kernel_size=kernel_size,
)
self.conv2 = ConvNormPool(
input_size=hid_size,
hidden_size=hid_size,
kernel_size=kernel_size,
)
self.avgpool = nn.AdaptiveMaxPool1d((1))
self.attn = nn.Linear(hid_size, hid_size, bias=False)
self.fc = nn.Linear(in_features=hid_size, out_features=n_classes)

def forward(self, input):
    x = self.conv1(input)
    x = self.conv2(x)
    x_out, hid_states = self.rnn_layer(x)
    x = torch.cat([hid_states[0], hid_states[1]], dim=0).transpose(0, 1)
    x_attn = torch.tanh(self.attn(x))
    x = x_attn.bmm(x_out)
    x = x.transpose(2, 1)
    x = self.avgpool(x)
    x = x.view(-1, x.size(1) * x.size(2))
    x = F.softmax(self.fc(x), dim=-1)
    return x

class Meter:
def init(self, n_classes=5):
self.metrics = {}
self.confusion = torch.zeros((n_classes, n_classes))

def update(self, x, y, loss):
    x = np.argmax(x.detach().cpu().numpy(), axis=1)
    y = y.detach().cpu().numpy()
    self.metrics['loss'] += loss
    self.metrics['accuracy'] += accuracy_score(x,y)
    self.metrics['f1'] += f1_score(x,y,average='macro')
    self.metrics['precision'] += precision_score(x, y, average='macro', zero_division=1)
    self.metrics['recall'] += recall_score(x,y, average='macro', zero_division=1)
    
     
    self._compute_cm(x, y)
    
def _compute_cm(self, x, y):
    for prob, target in zip(x, y):
        if prob == target:
            self.confusion[target][target] += 1
        else:
            self.confusion[target][prob] += 1

def init_metrics(self):
    self.metrics['loss'] = 0
    self.metrics['accuracy'] = 0
    self.metrics['f1'] = 0
    self.metrics['precision'] = 0
    self.metrics['recall'] = 0
    
def get_metrics(self):
    return self.metrics

def get_confusion_matrix(self):
    return self.confusion

class Trainer:
def init(self, net, lr, batch_size, num_epochs):
self.net = net.to(config.device)
self.num_epochs = num_epochs
self.criterion = nn.CrossEntropyLoss()
self.optimizer = AdamW(self.net.parameters(), lr=lr)
self.scheduler = CosineAnnealingLR(self.optimizer, T_max=num_epochs, eta_min=5e-6)
self.best_loss = float(‘inf’)
self.phases = [‘train’, ‘val’]
self.dataloaders = {
phase: get_dataloader(phase, batch_size) for phase in self.phases
}
self.train_df_logs = pd.DataFrame()
self.val_df_logs = pd.DataFrame()

def _train_epoch(self, phase):
    print(f"{phase} mode | time: {time.strftime('%H:%M:%S')}")
    
    self.net.train() if phase == 'train' else self.net.eval()
    meter = Meter()
    meter.init_metrics()
    
    for i, (data, target) in enumerate(self.dataloaders[phase]):
        data = data.to(config.device)
        target = target.to(config.device)
        
        output = self.net(data)
        loss = self.criterion(output, target)
                    
        if phase == 'train':
            self.optimizer.zero_grad()
            loss.backward()
            self.optimizer.step()
        
        meter.update(output, target, loss.item())
         
    metrics = meter.get_metrics()
    metrics = {k:v / i for k, v in metrics.items()}
    df_logs = pd.DataFrame([metrics])
    confusion_matrix = meter.get_confusion_matrix()
    
    if phase == 'train':
        self.train_df_logs = pd.concat([self.train_df_logs, df_logs], axis=0)
    else:
        self.val_df_logs = pd.concat([self.val_df_logs, df_logs], axis=0)
    
    # show logs
    print('{}: {}, {}: {}, {}: {}, {}: {}, {}: {}'
          .format(*(x for kv in metrics.items() for x in kv))
         )
    fig, ax = plt.subplots(figsize=(5, 5))
    cm_ = ax.imshow(confusion_matrix, cmap='hot')
    ax.set_title('Confusion matrix', fontsize=15)
    ax.set_xlabel('Actual', fontsize=13)
    ax.set_ylabel('Predicted', fontsize=13)
    plt.colorbar(cm_)
    plt.show()
    return loss

def run(self):
    for epoch in range(self.num_epochs):
        self._train_epoch(phase='train')
        with torch.no_grad():
            val_loss = self._train_epoch(phase='val')
            self.scheduler.step()
        
        if val_loss < self.best_loss:
            self.best_loss = val_loss
            print('\nNew checkpoint\n')
            self.best_loss = val_loss
            torch.save(self.net.state_dict(), f"best_model_epoc{epoch}.pth")
        #clear_output()

#model = RNNAttentionModel(1, 64, ‘lstm’, False)
#model = RNNModel(1, 64, ‘lstm’, True)

#model = RNNAttentionModel(1, 64, ‘lstm’, False)
#model = RNNModel(1, 64, ‘lstm’, True)
model = CNN(num_classes=5, hid_size=128)
trainer = Trainer(net=model, lr=1e-3, batch_size=96, num_epochs=10)#100)
trainer.run()
train_logs = trainer.train_df_logs
train_logs.columns = [“train_”+ colname for colname in train_logs.columns]
val_logs = trainer.val_df_logs
val_logs.columns = [“val_”+ colname for colname in val_logs.columns]

logs = pd.concat([train_logs,val_logs], axis=1)
logs.reset_index(drop=True, inplace=True)
logs = logs.loc[:, [
‘train_loss’, ‘val_loss’,
‘train_accuracy’, ‘val_accuracy’,
‘train_f1’, ‘val_f1’,
‘train_precision’, ‘val_precision’,
‘train_recall’, ‘val_recall’]
]
logs.head()
logs.to_csv(‘cnn.csv’, index=False)
cnn_model = CNN(num_classes=5, hid_size=128).to(config.device)
cnn_model.load_state_dict(
torch.load(config.cnn_state_path,
map_location=config.device)
);
cnn_model.eval();
logs = pd.read_csv(config.cnn_logs)
colors = [’#C042FF’, ‘#03C576FF’, ‘#FF355A’, ‘#03C5BF’, ‘#96C503’, ‘#C5035B’]
palettes = [sns.color_palette(colors, 2),
sns.color_palette(colors, 4),
sns.color_palette(colors[:2]+colors[-2:] + colors[2:-2], 6)]

fig, ax = plt.subplots(1, 2, figsize=(12, 4))

sns.lineplot(data=logs.iloc[:, :2], palette=palettes[0], markers=True, ax=ax[0], linewidth=2.5,)
ax[0].set_title(“Loss Function during Model Training”, fontsize=14)
ax[0].set_xlabel(“Epoch”, fontsize=14)

sns.lineplot(data=logs.iloc[:, 2:6], palette=palettes[1], markers=True, ax=ax[1], linewidth=2.5, legend=“full”)
ax[1].set_title(“Metrics during Model Training”, fontsize=15)
ax[1].set_xlabel(“Epoch”, fontsize=14)

plt.suptitle(‘CNN Model’, fontsize=18)

plt.tight_layout()
fig.savefig(“cnn.png”, format=“png”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
fig.savefig(“cnn.svg”, format=“svg”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
lstm_model = RNNModel(1, 64, ‘lstm’, True).to(config.device)
lstm_model.load_state_dict(
torch.load(config.lstm_state_path,
map_location=config.device)
);
lstm_model.eval();
logs = pd.read_csv(config.lstm_logs)
colors = [’#C042FF’, ‘#03C576FF’, ‘#FF355A’, ‘#03C5BF’, ‘#96C503’, ‘#C5035B’]
palettes = [sns.color_palette(colors, 2),
sns.color_palette(colors, 4),
sns.color_palette(colors[:2]+colors[-2:] + colors[2:-2], 6)]

fig, ax = plt.subplots(1, 2, figsize=(12, 4))

sns.lineplot(data=logs.iloc[:, :2], palette=palettes[0], markers=True, ax=ax[0], linewidth=2.5,)
ax[0].set_title(“Loss Function during Model Training”, fontsize=14)
ax[0].set_xlabel(“Epoch”, fontsize=14)

sns.lineplot(data=logs.iloc[:, 2:6], palette=palettes[1], markers=True, ax=ax[1], linewidth=2.5, legend=“full”)
ax[1].set_title(“Metrics during Model Training”, fontsize=15)
ax[1].set_xlabel(“Epoch”, fontsize=14)

plt.suptitle(‘CNN+LSTM Model’, fontsize=18)

plt.tight_layout()
fig.savefig(“lstm.png”, format=“png”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
fig.savefig(“lstm.svg”, format=“svg”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
attn_model = RNNAttentionModel(1, 64, ‘lstm’, False).to(config.device)
attn_model.load_state_dict(
torch.load(config.attn_state_path,
map_location=config.device)
);
attn_model.eval();
logs = pd.read_csv(config.attn_logs)
colors = [’#C042FF’, ‘#03C576FF’, ‘#FF355A’, ‘#03C5BF’, ‘#96C503’, ‘#C5035B’]
palettes = [sns.color_palette(colors, 2),
sns.color_palette(colors, 4),
sns.color_palette(colors[:2]+colors[-2:] + colors[2:-2], 6)]

fig, ax = plt.subplots(1, 2, figsize=(12, 4))

sns.lineplot(data=logs.iloc[:, :2], palette=palettes[0], markers=True, ax=ax[0], linewidth=2.5,)
ax[0].set_title(“Loss Function during Model Training”, fontsize=14)
ax[0].set_xlabel(“Epoch”, fontsize=14)

sns.lineplot(data=logs.iloc[:, 2:6], palette=palettes[1], markers=True, ax=ax[1], linewidth=2.5, legend=“full”)
ax[1].set_title(“Metrics during Model Training”, fontsize=15)
ax[1].set_xlabel(“Epoch”, fontsize=14)

plt.suptitle(‘CNN+LSTM+Attention Model’, fontsize=18)

plt.tight_layout()
fig.savefig(“attn.png”, format=“png”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
fig.savefig(“attn.svg”, format=“svg”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
test_df = pd.read_csv(config.test_csv_path)
print(test_df.shape)
test_dataset = ECGDataset(test_df)
test_dataloader = DataLoader(dataset=test_dataset, batch_size=96, num_workers=0, shuffle=False)
def make_test_stage(dataloader, model, probs=False):
cls_predictions = []
cls_ground_truths = []

for i, (data, cls_target) in enumerate(dataloader):
    with torch.no_grad():

        data = data.to(config.device)
        cls_target = cls_target.cpu()
        cls_prediction = model(data)
        
        if not probs:
            cls_prediction = torch.argmax(cls_prediction, dim=1)

        cls_predictions.append(cls_prediction.detach().cpu())
        cls_ground_truths.append(cls_target)

predictions_cls = torch.cat(cls_predictions).numpy()
ground_truths_cls = torch.cat(cls_ground_truths).numpy()
return predictions_cls, ground_truths_cls

models = [cnn_model, lstm_model, attn_model]
y_pred, y_true = make_test_stage(test_dataloader, models[0])
y_pred.shape, y_true.shape
report = pd.DataFrame(
classification_report(
y_pred,
y_true,
output_dict=True
)
).transpose()
colors = [’#00FA9A’, ‘#D2B48C’, ‘#FF69B4’]#random.choices(list(mcolors.CSS4_COLORS.values()), k = 3)
report_plot = report.apply(lambda x: x*100)
ax = report_plot[[“precision”, “recall”, “f1-score”]].plot(kind=‘bar’,
figsize=(13, 4), legend=True, fontsize=15, color=colors)

ax.set_xlabel(“Estimators”, fontsize=15)
ax.set_xticklabels(
list(id_to_label.values())+[“accuracy avg”, “marco avg”, “weighted avg”],
rotation=15, fontsize=11)
ax.set_ylabel(“Percentage”, fontsize=15)
plt.title(“CNN Model Classification Report”, fontsize=20)

for percentage, p in zip(
report[[‘precision’, ‘recall’, ‘f1-score’]].values,
ax.patches):
percentage = " ".join([str(round(i100, 2))+"%" for i in percentage])
x = p.get_x() + p.get_width() - 0.4
y = p.get_y() + p.get_height() / 4
ax.annotate(percentage, (x, y), fontsize=8, rotation=15, fontweight=‘bold’)
fig.savefig(“cnn_report.png”, format=“png”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
fig.savefig(“cnn_report.svg”, format=“svg”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
plt.show()
y_pred, y_true = make_test_stage(test_dataloader, models[1])
y_pred.shape, y_true.shape
report = pd.DataFrame(
classification_report(
y_pred,
y_true,
output_dict=True
)
).transpose()
colors = [’#00FA9A’, ‘#D2B48C’, ‘#FF69B4’]#random.choices(list(mcolors.CSS4_COLORS.values()), k = 3)
report_plot = report.apply(lambda x: x
100)
ax = report_plot[[“precision”, “recall”, “f1-score”]].plot(kind=‘bar’,
figsize=(13, 4), legend=True, fontsize=15, color=colors)

ax.set_xlabel(“Estimators”, fontsize=15)
ax.set_xticklabels(
list(id_to_label.values())+[“accuracy avg”, “marco avg”, “weighted avg”],
rotation=15, fontsize=11)
ax.set_ylabel(“Percentage”, fontsize=15)
plt.title(“CNN+LSTM Model Classification Report”, fontsize=20)

for percentage, p in zip(
report[[‘precision’, ‘recall’, ‘f1-score’]].values,
ax.patches):

percentage = " ".join([str(round(i*100, 2))+"%" for i in percentage])
x = p.get_x() + p.get_width() - 0.4
y = p.get_y() + p.get_height() / 4
ax.annotate(percentage, (x, y), fontsize=8, rotation=15, fontweight='bold')
fig.savefig("lstm_report.png", format="png",  pad_inches=0.2, transparent=False, bbox_inches='tight')

fig.savefig(“lstm_report.svg”, format=“svg”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
plt.show()
y_pred, y_true = make_test_stage(test_dataloader, models[2])
y_pred.shape, y_true.shape
report = pd.DataFrame(
classification_report(
y_pred,
y_true,
output_dict=True
)
).transpose()
colors = [’#00FA9A’, ‘#D2B48C’, ‘#FF69B4’]#random.choices(list(mcolors.CSS4_COLORS.values()), k = 3)
report_plot = report.apply(lambda x: x*100)
ax = report_plot[[“precision”, “recall”, “f1-score”]].plot(kind=‘bar’,
figsize=(13, 4), legend=True, fontsize=15, color=colors)

ax.set_xlabel(“Estimators”, fontsize=15)
ax.set_xticklabels(
list(id_to_label.values())+[“accuracy avg”, “marco avg”, “weighted avg”],
rotation=15, fontsize=11)
ax.set_ylabel(“Percentage”, fontsize=15)
plt.title(“CNN+LSTM+Attention Model Classification Report”, fontsize=20)

for percentage, p in zip(
report[[‘precision’, ‘recall’, ‘f1-score’]].values,
ax.patches):
percentage = " “.join([str(round(i*100, 2))+”%" for i in percentage])
x = p.get_x() + p.get_width() - 0.4
y = p.get_y() + p.get_height() / 4
ax.annotate(percentage, (x, y), fontsize=8, rotation=15, fontweight=‘bold’)
fig.savefig(“attn_report.png”, format=“png”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
fig.savefig(“attn_report.svg”, format=“svg”, pad_inches=0.2, transparent=False, bbox_inches=‘tight’)
plt.show()
y_pred = np.zeros((y_pred.shape[0], 5), dtype=np.float32)
for i, model in enumerate(models, 1):
y_pred_, y_true = make_test_stage(test_dataloader, model, True)
y_pred += y_pred_
y_pred /= i
y_pred = np.argmax(y_pred, axis=1)
clf_report = classification_report(y_pred,
y_true,
labels=[0,1,2,3,4],
target_names=list(id_to_label.values()),#[‘N’, ‘S’, ‘V’, ‘F’, ‘Q’],
output_dict=True)

plt.figure(figsize=(10, 8))
ax = sns.heatmap(pd.DataFrame(clf_report).iloc[:-1, :].T, annot=True)
ax.set_xticklabels(ax.get_xticklabels(),fontsize=15)
ax.set_yticklabels(ax.get_yticklabels(),fontsize=12, rotation=0)
plt.title(“Ensemble Classification Report”, fontsize=20)
plt.savefig(f"ensemble result.svg",format=“svg”,bbox_inches=‘tight’, pad_inches=0.2)
plt.savefig(f"ensemble result.png", format=“png”,bbox_inches=‘tight’, pad_inches=0.2)
clf_report