티스토리 뷰

728x90

www.dacon.io/competitions/open/235594/overview/

 

[이미지] Fashion MNIST : 의류 클래스 예측

출처 : DACON - Data Science Competition

dacon.io


1. Dataset 구축

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class DatasetFashion(data.Dataset):
    def __init__(self,file_path,test_mode=False,train=True,transform=None):
        data=pd.read_csv(file_path,index_col='index')
        self.test_mode=test_mode
        self.train=train
        self.dataframe=list(data.values)
        self.transform=transform
        # train, validation
        image=[]
        label=[]
        if test_mode==False :
            #Train mode get data -> train data (train,vali)
            train_len=int(len(self.dataframe)*0.8)
            if self.train : # train
                for idx in range(0,train_len) :
                    label.append(self.dataframe[idx][0])
                    image.append(self.dataframe[idx][1:])
                self.labels=np.asarray(label)
                self.images=np.asarray(image).reshape(-1,28,28,1).astype('float32')
            else : # validation
                for idx in range(train_len,len(self.dataframe)) :
                    label.append(self.dataframe[idx][0])
                    image.append(self.dataframe[idx][1:])
                self.labels=np.asarray(label)
                self.images=np.asarray(image).reshape(-1,28,28,1).astype('float32')
        else :
            # Last Test Mode -> All train (train+vali) -> test result (csv)
            # All train
            if self.train :
                for line in self.dataframe :
                    label.append(line[0])
                    image.append(line[1:])
                self.labels=np.asarray(label)
                self.images=np.asarray(image).reshape(-1,28,28,1).astype('float32')
            else :
                for line in self.dataframe :
                    label.append(0)
                    image.append(line[0:])
                self.labels=np.asarray(label)
                self.images=np.asarray(image).reshape(-1,28,28,1).astype('float32')
 
    
    def __len__(self):
        return len(self.images)
    
    def __getitem__(self,index):
        label=self.labels[index]
        image=self.images[index]
        if self.transform!=None:
            image=self.transform(image)
        return image,label
cs

Data augmentation 적용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class AddGaussianNoise(object):
    def __init__(self, mean=0., std=1.):
        self.std = std
        self.mean = mean
        
    def __call__(self, tensor):
        return tensor + torch.randn(tensor.size()) * self.std + self.mean
    
    def __repr__(self):
        return self.__class__.__name__ + '(mean={0}, std={1})'.format(self.mean, self.std)
 
def get_data():
    rgb_mean = (0.5,)
    rgb_std = (0.5,)
    train_transforms=transforms.Compose([transforms.ToTensor(),
                                        transforms.RandomRotation(30),
                                        transforms.RandomHorizontalFlip(),
                                        transforms.Normalize(rgb_mean,rgb_std),
                                        transforms.RandomApply([AddGaussianNoise(0.,1.)],p=0.2)])
    vali_transforms=transforms.Compose([transforms.ToTensor(),
                                        transforms.Normalize(rgb_mean,rgb_std)])
    #train_data=DatasetFashion('./datasets/train.csv',test_mode=False,train=True,transform=train_transforms)
    vali_data=DatasetFashion('./datasets/train.csv',test_mode=False,train=False,transform=vali_transforms)
    #TEST MODE ---------
    train_data=DatasetFashion('./datasets/train.csv',test_mode=True,train=True,transform=train_transforms)
    test_data=DatasetFashion('./datasets/test.csv',test_mode=True,train=False,transform=vali_transforms)
    #-------------------
    train_iter=torch.utils.data.DataLoader(train_data,batch_size=BATCH_SIZE,shuffle=True,num_workers=1)
    vali_iter=torch.utils.data.DataLoader(vali_data,batch_size=BATCH_SIZE,shuffle=True,num_workers=1)
    test_iter=torch.utils.data.DataLoader(test_data,batch_size=BATCH_SIZE,shuffle=False,num_workers=1)
    return train_iter,vali_iter,test_iter
cs

 

2. Model 설계 및 구축

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class CNN(nn.Module):
    # Made by hunmin-hub
    def __init__(self,name='cnn',imageSize=[28,28],input_channel=1,start_channels=[32,64],block_channels=[128,256],block_loof=2,out_channel=10):
        super(CNN,self).__init__()
        self.kernel_size=3
        self.imageSize=imageSize
        self.input_channel=input_channel
        self.start_channels=start_channels
        self.block_channels=block_channels
        self.out_channel=out_channel
        self.block_loof=block_loof # block_loof count
        self.block_inchannel=start_channels[-1# block input_channel = start_layers out channel
        #NET
        self.relu=nn.ReLU(inplace=True)
        self.start_net=self.start_layer()
        #Block Net
        self.block_net=self.make_blocklayer()
        #Output Net
        self.output_net=self.output_layer()
    
    def start_layer(self): # 1-> 32 -> 64 / Size : 28 -> 14 -> 7
        layers=[]
        prev_channel=self.input_channel
        for current_channel in self.start_channels :
            layers.append(nn.Conv2d(in_channels=prev_channel,
                                    out_channels=current_channel,
                                    kernel_size=self.kernel_size,
                                    stride=(1,1),
                                    padding=((self.kernel_size-1)//2)))
            layers.append(nn.BatchNorm2d(current_channel))
            layers.append(nn.ReLU(True))
            #layers.append(nn.Dropout2d(p=0.5))
            layers.append(nn.MaxPool2d(kernel_size=(2,2),stride=(2,2)))
            prev_channel=current_channel
        return nn.Sequential(*layers)
 
    def make_blocklayer(self):
        layers=[]
        for _ in range(self.block_loof):
            layers.append(BlockNet(in_channel=self.block_inchannel,mid_channel=self.block_channels,out_channel=self.block_channels[0]))
            #layers.append(nn.Dropout2d(p=0.5))
            layers.append(nn.MaxPool2d(kernel_size=(2,2),stride=(2,2)))
            self.block_inchannel=self.block_channels[0]
            for idx in range(len(self.block_channels)):
                self.block_channels[idx]*=2
        return nn.Sequential(*layers)
    
    def output_layer(self):
        layers=[]
        layers.append(nn.Conv2d(in_channels=self.block_inchannel,
                                out_channels=self.out_channel,
                                kernel_size=(1,1),
                                stride=(1,1)))
        return nn.Sequential(*layers)
 
    def forward(self,x) :
        x=self.start_net(x)
        x=self.block_net(x)
        x=self.output_net(x)
        return F.log_softmax(x,dim=1)
 
    def init_params(self) :
        for m in self.modules() :
            if isinstance(m,nn.Conv2d) :
                nn.init.kaiming_normal_(m.weight)
                nn.init.zeros_(m.bias)
            elif isinstance(m,nn.BatchNorm2d) :
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)
 
 
class BlockNet(nn.Module):
    def __init__(self,in_channel=64,mid_channel=[128,256],out_channel=128):
        super(BlockNet,self).__init__()
        self.in_channel=in_channel
        self.mid_channel=mid_channel
        self.out_channel=out_channel
        self.kernel_size=3
        # net
        self.relu=nn.ReLU(inplace=True)
        self.channel_change_net=self.channel_change_layer()
        self.block_net=self.Block_layer()
 
    def channel_change_layer(self):
        layers=[]
        layers.append(nn.Conv2d(in_channels=self.in_channel,
                                out_channels=self.out_channel,
                                kernel_size=(1,1),
                                stride=(1,1)))
        layers.append(nn.BatchNorm2d(self.out_channel))
        return nn.Sequential(*layers)
 
    def Block_layer(self):
        layers=[]
        prev_channel=self.in_channel
        for current_channel in self.mid_channel :
            layers.append(nn.Conv2d(in_channels=prev_channel,
                                    out_channels=current_channel,
                                    kernel_size=self.kernel_size,
                                    stride=(1,1),
                                    padding=((self.kernel_size-1)//2)))
            layers.append(nn.BatchNorm2d(current_channel))
            layers.append(nn.ReLU(True))
            prev_channel=current_channel
        layers.append(nn.Conv2d(in_channels=prev_channel,
                                out_channels=self.out_channel,
                                kernel_size=(1,1),
                                stride=(1,1)))
        return nn.Sequential(*layers)
    
    def forward(self,x):
        identity=self.channel_change_net(x)
        x=self.block_net(x)
        x+=identity
        x=self.relu(x)
        return x
cs

 

3. 결과

전체 소스코드는 github.com/hunmin-hub/DL_Tutorial/tree/main/DACON_Fashion

'Deep Learning > CV' 카테고리의 다른 글

롯데정보통신 Vision AI 경진대회 - Public LB 2nd place Solution  (5) 2021.03.28
U-net 구현  (0) 2021.03.07
[DACON] Mnist 숫자 사진 분류  (0) 2021.02.12
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함