Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
3c90a0a
austin
glcanvas Dec 3, 2019
102a0fc
austin gain
glcanvas Dec 5, 2019
accb0cd
austin gain
glcanvas Dec 7, 2019
4489830
austin gain gpu support
glcanvas Dec 8, 2019
aa6fdf5
add classifier
glcanvas Dec 8, 2019
01dc560
add classifier
glcanvas Dec 9, 2019
3e4c032
classifier
glcanvas Dec 11, 2019
1e656f8
classifier & gain
glcanvas Dec 13, 2019
4f70f52
project structure improve
glcanvas Dec 16, 2019
778eedf
project structure improve
glcanvas Dec 17, 2019
4db5259
project structure improve
glcanvas Dec 17, 2019
b29d0a1
project structure improve
glcanvas Dec 17, 2019
4adfba7
project structure improve
glcanvas Dec 28, 2019
ba71a86
add log file select
glcanvas Dec 28, 2019
b9915f0
gain rewrite
glcanvas Dec 28, 2019
0be27ad
gain fix accuracy formula
glcanvas Dec 30, 2019
0dea3aa
gain fix accuracy formula
glcanvas Dec 31, 2019
88326e2
gain fix accuracy formula
glcanvas Dec 31, 2019
96f4788
rewrite gain split
glcanvas Jan 1, 2020
b5785fb
merge with remove server
glcanvas Jan 1, 2020
e7fd9f3
ability to launch local and remote
glcanvas Jan 1, 2020
88ae67b
gain.sh
glcanvas Jan 1, 2020
7258d1b
executable
glcanvas Jan 1, 2020
e53fb3d
Merge branch 'AustinDoolittle' of https://github.com/glcanvas/ml-dipl…
glcanvas Jan 1, 2020
1866490
gain.sh
glcanvas Jan 1, 2020
6443fcf
visualize plots
glcanvas Jan 1, 2020
5c311d8
Using gradient as in original paper
tanyapole Jan 3, 2020
2c51380
Merge pull request #4 from glcanvas/fix-to-as-in-paper
glcanvas Jan 3, 2020
270dc37
gain.sh
glcanvas Jan 3, 2020
baf2e44
reduce cells, shuffle data
glcanvas Jan 3, 2020
f367ca9
not to github
glcanvas Jan 3, 2020
c5efcc8
add a lot of metrics, rewrite output
glcanvas Jan 4, 2020
d9f9eee
rename logs
glcanvas Jan 4, 2020
ec1ee50
not to github
glcanvas Jan 4, 2020
6cdc00a
fix gain metrics
glcanvas Jan 6, 2020
eae704d
improve plot visualize
glcanvas Jan 6, 2020
9ab3f5f
improve plot visualize
glcanvas Jan 6, 2020
30f817f
review accuracy
glcanvas Jan 6, 2020
a0a687f
not to github
glcanvas Jan 6, 2020
cdea02d
not to github
glcanvas Jan 7, 2020
7484621
fix plot visualize, visualize all plots
glcanvas Jan 7, 2020
aff6e55
gain grad after feature name
glcanvas Jan 25, 2020
635f814
gain grad after feature name visualize
glcanvas Jan 27, 2020
8838859
not to github
glcanvas Jan 28, 2020
9e90997
Merge branch 'AustinDoolittle' of https://github.com/glcanvas/ml-dipl…
glcanvas Jan 28, 2020
d2d3f57
measure fix 2git add -Agit add -A
glcanvas Feb 3, 2020
9ddc6df
classifier fix
glcanvas Feb 3, 2020
85fa22c
fix cl
glcanvas Feb 3, 2020
4d60585
remove images
glcanvas Feb 16, 2020
9264bb6
Merge remote-tracking branch 'origin/AustinDoolittle' into AustinDool…
glcanvas Feb 16, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# ml-diplom
AustinDoolittle implementation

wia anaconda pip
opencv-python
imgaug


---------
fastai
Binary file added __pycache__/cbam_model.cpython-36.pyc
Binary file not shown.
Binary file added __pycache__/classifier.cpython-36.pyc
Binary file not shown.
Binary file added __pycache__/gain.cpython-36.pyc
Binary file not shown.
Binary file added __pycache__/image_loader.cpython-36.pyc
Binary file not shown.
Binary file added __pycache__/main_cbam.cpython-36.pyc
Binary file not shown.
Binary file added __pycache__/property.cpython-36.pyc
Binary file not shown.
Binary file added __pycache__/sam_model.cpython-36.pyc
Binary file not shown.
Binary file added __pycache__/sam_train.cpython-36.pyc
Binary file not shown.
Binary file added __pycache__/utils.cpython-36.pyc
Binary file not shown.
232 changes: 232 additions & 0 deletions classifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
"""
classify dataset
"""

import torch
import torchvision.models as m
import property as P
import torch.nn as nn
import copy
from datetime import datetime
import os
import utils

probability_threshold = 0.5


def scalar(tensor):
return tensor.data.cpu().item()


def send_to_gpu(*args) -> tuple:
result = []
for i in args:
result.append(i.cuda())
return (*result,)


def send_to_cpu(*args) -> tuple:
result = []
for i in args:
result.append(i.cpu())
return (*result,)


class Classifier:

def __init__(self, description: str, classes: int, gpu=False, loss_classifier=None):
self.gpu = gpu
self.description = description
# здесь * 2 так как каждой метке соответсвует бинарное значение -- да, нет в самом деле я сделал так для
# классификации так как сделать по другому не знаю
self.classes = classes
self.model = m.vgg16(pretrained=True)
num_features = self.model.classifier[6].in_features
self.model.classifier[6] = nn.Linear(num_features, self.classes)

self.best_weights = copy.deepcopy(self.model.state_dict())
self.best_test_weights = copy.deepcopy(self.model.state_dict())

if loss_classifier is None:
self.loss_classifier = torch.nn.BCELoss()

if self.gpu:
self.model = self.model.cuda()
self.tensor_source = torch.cuda
else:
self.tensor_source = torch

self.train_model_answers = [[] for _ in range(self.classes)]
self.train_trust_answers = [[] for _ in range(self.classes)]
self.train_probabilities = [[] for _ in range(self.classes)]

self.test_model_answers = [[] for _ in range(self.classes)]
self.test_trust_answers = [[] for _ in range(self.classes)]
self.test_probabilities = [[] for _ in range(self.classes)]

def train(self, epochs: int, test_each_epochs: int, save_test_roc_each_epochs: int, save_train_roc_each_epochs: int,
train_data_set, test_data_set,
learning_rate=1e-6):

optimizer = torch.optim.Adam(self.model.parameters(), lr=learning_rate)
self.model.train()
best_loss = None
best_test_loss = None

for epoch in range(1, epochs + 1):
total_loss_cl = 0
total_cl_acc = 0
set_size = 0
for images, _, labels in train_data_set:
set_size += 1 # images.size(0)
if self.gpu:
images, labels = send_to_gpu(images, labels)
# images, labels = wrap_to_variable(images, labels)
class_label = labels
train_batch_size = labels.shape[0]
self.model.zero_grad()
output_cl = self.model(images)

sigmoid = nn.Sigmoid() # used for calculate accuracy
output_cl = sigmoid(output_cl)
loss_cl = self.loss_classifier(output_cl, class_label)

loss_cl.backward()
optimizer.step()

total_loss_cl, total_cl_acc, output_cl, output_probability = self.__calculate_accuracy(output_cl,
class_label,
train_batch_size,
loss_cl,
total_loss_cl,
total_cl_acc)

labels = labels.cpu()
output_cl = output_cl.cpu()
output_probability = output_probability.cpu()
for i in range(output_cl.shape[1]):
self.train_trust_answers[i].extend(labels[:, i].tolist())
self.train_model_answers[i].extend(output_cl[:, i].tolist())
self.train_probabilities[i].extend(output_probability[:, i].tolist())

torch.cuda.empty_cache()

if best_loss is None or total_loss_cl < best_loss:
best_loss = total_loss_cl
self.best_weights = copy.deepcopy(self.model.state_dict())

f_1_score_text, recall_score_text, precision_score_text = utils.calculate_metric(self.classes,
self.train_trust_answers,
self.train_model_answers)
text = "TRAIN={} Loss_CL={:.10f} Accuracy_CL_Percent={:.5f} {} {} {} ".format(epoch,
total_loss_cl / set_size,
total_cl_acc / set_size,
f_1_score_text,
recall_score_text,
precision_score_text)
if epoch % save_train_roc_each_epochs == 0:
auc_roc = "auc_roc="
for idx, i in enumerate(self.train_trust_answers):
auc_roc += "trust_{}={}".format(idx, ",".join(list(map(lambda x: "{}".format(x), i))))
for idx, i in enumerate(self.train_probabilities):
auc_roc += "prob_{}={}".format(idx, ",".join(list(map(lambda x: "{:.5f}".format(x), i))))
text += auc_roc

print(text)
P.write_to_log(text)
if epoch % test_each_epochs == 0:
test_loss, _ = self.test(test_data_set, epoch, save_test_roc_each_epochs)
if best_test_loss is None or test_loss < best_test_loss:
best_test_loss = test_loss
self.best_test_weights = copy.deepcopy(self.model.state_dict())

self.train_model_answers = [[] for _ in range(self.classes)]
self.train_trust_answers = [[] for _ in range(self.classes)]
self.test_model_answers = [[] for _ in range(self.classes)]
self.test_trust_answers = [[] for _ in range(self.classes)]
self.train_probabilities = [[] for _ in range(self.classes)]
self.test_probabilities = [[] for _ in range(self.classes)]

self.save_model(self.best_test_weights, "classifier_test_weights")
self.save_model(self.best_weights, "classifier_train_weights")

def test(self, test_data_set, epoch: int, save_test_roc_each_epoch: int):
test_total_loss_cl = 0
test_total_cl_acc = 0
test_size = 0
for images, _, labels in test_data_set:
test_size += 1 # images.size(0)
if self.gpu:
images, labels = send_to_gpu(images, labels)
class_label = labels
batch_size = labels.shape[0]
output_cl = self.model(images)

grad_target = output_cl * class_label
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why to compute the gradient during model evaluation?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

described, resolved

Copy link
Owner Author

@glcanvas glcanvas Dec 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this is redudant because in lines bellow:

loss_cl = self.loss_classifier(output_cl, class_label)
loss_cl.backward()
optimizer.step()``` 
we do the same

grad_target.backward(gradient=class_label * output_cl, retain_graph=True)

sigmoid = nn.Sigmoid() # used for calculate accuracy
output_cl = sigmoid(output_cl)
loss_cl = self.loss_classifier(output_cl, class_label)

test_total_loss_cl, test_total_cl_acc, output_cl, output_probability = self.__calculate_accuracy(output_cl,
class_label,
batch_size,
loss_cl,
test_total_loss_cl,
test_total_cl_acc)
labels = labels.cpu()
output_cl = output_cl.cpu()
output_probability = output_probability.cpu()
for i in range(output_cl.shape[1]):
self.test_trust_answers[i].extend(labels[:, i].tolist())
self.test_model_answers[i].extend(output_cl[:, i].tolist())
self.test_probabilities[i].extend(output_probability[:, i].tolist())

# test_size = len(test_data_set)
test_total_loss_cl /= test_size
test_total_cl_acc /= test_size

f_1_score_text, recall_score_text, precision_score_text = utils.calculate_metric(self.classes,
self.test_trust_answers,
self.test_model_answers)
text = "TEST Loss_CL={:.10f} Accuracy_CL_Percent={:.5f} {} {} {} ".format(test_total_loss_cl,
test_total_cl_acc,
f_1_score_text,
recall_score_text,
precision_score_text)
if epoch % save_test_roc_each_epoch == 0:
auc_roc = "auc_roc="
for idx, i in enumerate(self.test_trust_answers):
auc_roc += "trust_{}={}".format(idx, ",".join(list(map(lambda x: "{}".format(x), i))))
for idx, i in enumerate(self.test_probabilities):
auc_roc += "prob_{}={}".format(idx, ",".join(list(map(lambda x: "{:.5f}".format(x), i))))
text += auc_roc

print(text)
P.write_to_log(text)

return test_total_loss_cl, test_total_cl_acc

def save_model(self, weights, name="classifier-model"):
try:
name = name + self.description + datetime.today().strftime('%Y-%m-%d-_-%H_%M_%S') + ".torch"
saved_dir = os.path.join(P.base_data_dir, 'classifier_weights')
os.makedirs(saved_dir, exist_ok=True)
saved_file = os.path.join(saved_dir, name)
torch.save(weights, saved_file)
print("Save model: {}".format(name))
P.write_to_log("Save model: {}".format(name))
except Exception as e:
print("Can't save model: {}".format(name), e)
P.write_to_log("Can't save model: {}".format(name), e)

def __calculate_accuracy(self, output_cl, class_label, batch_size, loss_cl, total_loss_cl, total_cl_acc):
output_probability = output_cl.clone()
output_cl[output_cl >= probability_threshold] = 1
output_cl[output_cl < probability_threshold] = 0
cl_acc = torch.eq(output_cl, class_label).sum()

total_loss_cl += scalar(loss_cl.sum()) / batch_size
total_cl_acc += scalar(cl_acc.sum()) / (batch_size * self.classes)
return total_loss_cl, total_cl_acc, output_cl, output_probability
18 changes: 18 additions & 0 deletions classifier.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 2000 --test_left 2001 --test_right 2592 --description new_measures

~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 500 --test_left 501 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 500 --test_left 501 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 500 --test_left 501 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 500 --test_left 501 --test_right 2592 --description new_measures

~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 1000 --test_left 1001 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 1000 --test_left 1001 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 1000 --test_left 1001 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 1000 --test_left 1001 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 1000 --test_left 1001 --test_right 2592 --description new_measures

~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 100 --test_left 101 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 100 --test_left 101 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 100 --test_left 101 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 100 --test_left 101 --test_right 2592 --description new_measures
~/nduginec_evn3/bin/python ~/ml-diplom/main_classifier.py --train_left 0 --train_right 100 --test_left 101 --test_right 2592 --description new_measures
Loading