crnn_layer
cnn๊ณผ rnn์ ๊ฒฐํฉํ layer ์ ๋๋ค.
rnn์์ fully connected ์ฐ์ฐ์ convolutional ์ฐ์ฐ์ผ๋ก ๋ฐ๋์ด์ง ๊ฒ ์ธ์ ๋ฑํ ๋ณํ๊ฐ ์์ต๋๋ค.
increment_layer
static void increment_layer(layer *l, int steps)
{
int num = l->outputs*l->batch*steps;
l->output += num;
l->delta += num;
l->x += num;
l->x_norm += num;
}
ํจ์ ์ด๋ฆ: increment_layer
์ ๋ ฅ:
layer ํฌ์ธํฐ l
int steps
๋์:
l์ output, delta, x, x_norm ํฌ์ธํฐ๋ฅผ steps * l->outputs * l->batch ๋งํผ ์ฆ๊ฐ์ํด
์ค๋ช :
์ด ํจ์๋ ๋ฏธ๋๋ฐฐ์น ์ฒ๋ฆฌ๋ฅผ ์ํด ํ์ํ ํจ์ ์ค ํ๋๋ก, ๊ฐ ๋ ์ด์ด์ ํฌ์ธํฐ๋ฅผ ๋ฏธ๋๋ฐฐ์น์ ๋ฐ๋ผ ์ ์ ํ ์ด๋์์ผ์ฃผ๋ ์ญํ ์ ํฉ๋๋ค.
์ด๋์์ผ์ผ ํ๋ ์์ steps * l->outputs * l->batch ๋ก ๊ณ์ฐ๋ฉ๋๋ค.
์ด ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ํ ๋ฒ์ ์ฒ๋ฆฌํด์ผ ํ๋ ๋ฏธ๋๋ฐฐ์น์ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ์ ์์ต๋๋ค.
forward_crnn_layer
void forward_crnn_layer(layer l, network net)
{
network s = net;
s.train = net.train;
int i;
layer input_layer = *(l.input_layer);
layer self_layer = *(l.self_layer);
layer output_layer = *(l.output_layer);
fill_cpu(l.outputs * l.batch * l.steps, 0, output_layer.delta, 1);
fill_cpu(l.hidden * l.batch * l.steps, 0, self_layer.delta, 1);
fill_cpu(l.hidden * l.batch * l.steps, 0, input_layer.delta, 1);
if(net.train) fill_cpu(l.hidden * l.batch, 0, l.state, 1);
for (i = 0; i < l.steps; ++i) {
s.input = net.input;
forward_convolutional_layer(input_layer, s);
s.input = l.state;
forward_convolutional_layer(self_layer, s);
float *old_state = l.state;
if(net.train) l.state += l.hidden*l.batch;
if(l.shortcut){
copy_cpu(l.hidden * l.batch, old_state, 1, l.state, 1);
}else{
fill_cpu(l.hidden * l.batch, 0, l.state, 1);
}
axpy_cpu(l.hidden * l.batch, 1, input_layer.output, 1, l.state, 1);
axpy_cpu(l.hidden * l.batch, 1, self_layer.output, 1, l.state, 1);
s.input = l.state;
forward_convolutional_layer(output_layer, s);
net.input += l.inputs*l.batch;
increment_layer(&input_layer, 1);
increment_layer(&self_layer, 1);
increment_layer(&output_layer, 1);
}
}
ํจ์ ์ด๋ฆ: forward_crnn_layer
์ ๋ ฅ:
layer l: CRNN ๋ ์ด์ด
network net: ๋ ์ด์ด๊ฐ ์ํ ๋คํธ์ํฌ
๋์:
CRNN ๋ ์ด์ด์ forward ์ฐ์ฐ์ ์ํํ๋ค.
์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ํ ์คํ ์ฉ ์ฒ๋ฆฌํ๋ฉฐ, ์ ๋ ฅ ๋ ์ด์ด, self ๋ ์ด์ด, ์ถ๋ ฅ ๋ ์ด์ด๋ฅผ ์ฐจ๋ก๋๋ก ๊ฑฐ์น๋ค.
๊ฐ ์คํ ์์ ์ ๋ ฅ, self ๋ ์ด์ด์ ์ถ๋ ฅ์ ๋ํ์ฌ state๋ฅผ ๊ตฌํ๊ณ , ์ถ๋ ฅ ๋ ์ด์ด๋ฅผ ๊ฑฐ์ณ ์ถ๋ ฅ์ ๊ณ์ฐํ๋ค.
๊ฐ ์คํ ์์ ์ฌ์ฉ๋ ๋ ์ด์ด์ ์ธ๋ฑ์ค๋ฅผ 1์ฉ ์ฆ๊ฐ์ํจ๋ค.
์ค๋ช :
CRNN(Convolutional Recurrent Neural Network)์ ์ปจ๋ณผ๋ฃจ์ ๋ ์ด์ด์ ์ํ ๋ ์ด์ด๊ฐ ๊ฒฐํฉ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋ ๋ฅ๋ฌ๋ ๋ชจ๋ธ์ด๋ค.
์ด ํจ์๋ CRNN ๋ ์ด์ด์ forward ์ฐ์ฐ์ ์ํํ๋ ํจ์์ด๋ค.
์ ๋ ฅ์ผ๋ก๋ CRNN ๋ ์ด์ด์ ๋ ์ด์ด๊ฐ ์ํ ๋คํธ์ํฌ๊ฐ ๋ค์ด์จ๋ค.
ํจ์ ๋ด๋ถ์์๋ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ํ ์คํ ์ฉ ์ฒ๋ฆฌํ๋ฉฐ, ์ ๋ ฅ ๋ ์ด์ด, self ๋ ์ด์ด, ์ถ๋ ฅ ๋ ์ด์ด๋ฅผ ์ฐจ๋ก๋๋ก ๊ฑฐ์น๋ค.
๊ฐ ์คํ ์์ ์ ๋ ฅ, self ๋ ์ด์ด์ ์ถ๋ ฅ์ ๋ํ์ฌ state๋ฅผ ๊ตฌํ๊ณ , ์ถ๋ ฅ ๋ ์ด์ด๋ฅผ ๊ฑฐ์ณ ์ถ๋ ฅ์ ๊ณ์ฐํ๋ค.
ํจ์ ๋ด๋ถ์์๋ ๊ฐ ์คํ ์์ ์ฌ์ฉ๋ ๋ ์ด์ด์ ์ธ๋ฑ์ค๋ฅผ 1์ฉ ์ฆ๊ฐ์ํจ๋ค.
backward_crnn_layer
void backward_crnn_layer(layer l, network net)
{
network s = net;
int i;
layer input_layer = *(l.input_layer);
layer self_layer = *(l.self_layer);
layer output_layer = *(l.output_layer);
increment_layer(&input_layer, l.steps-1);
increment_layer(&self_layer, l.steps-1);
increment_layer(&output_layer, l.steps-1);
l.state += l.hidden*l.batch*l.steps;
for (i = l.steps-1; i >= 0; --i) {
copy_cpu(l.hidden * l.batch, input_layer.output, 1, l.state, 1);
axpy_cpu(l.hidden * l.batch, 1, self_layer.output, 1, l.state, 1);
s.input = l.state;
s.delta = self_layer.delta;
backward_convolutional_layer(output_layer, s);
l.state -= l.hidden*l.batch;
/*
if(i > 0){
copy_cpu(l.hidden * l.batch, input_layer.output - l.hidden*l.batch, 1, l.state, 1);
axpy_cpu(l.hidden * l.batch, 1, self_layer.output - l.hidden*l.batch, 1, l.state, 1);
}else{
fill_cpu(l.hidden * l.batch, 0, l.state, 1);
}
*/
s.input = l.state;
s.delta = self_layer.delta - l.hidden*l.batch;
if (i == 0) s.delta = 0;
backward_convolutional_layer(self_layer, s);
copy_cpu(l.hidden*l.batch, self_layer.delta, 1, input_layer.delta, 1);
if (i > 0 && l.shortcut) axpy_cpu(l.hidden*l.batch, 1, self_layer.delta, 1, self_layer.delta - l.hidden*l.batch, 1);
s.input = net.input + i*l.inputs*l.batch;
if(net.delta) s.delta = net.delta + i*l.inputs*l.batch;
else s.delta = 0;
backward_convolutional_layer(input_layer, s);
increment_layer(&input_layer, -1);
increment_layer(&self_layer, -1);
increment_layer(&output_layer, -1);
}
}
ํจ์ ์ด๋ฆ: backward_crnn_layer
์ ๋ ฅ:
layer l: ์ญ์ ํ๋ฅผ ์ํํ CRNN ๋ ์ด์ด
network net: ๋ ์ด์ด๋ฅผ ํฌํจํ๋ ๋คํธ์ํฌ
๋์:
CRNN ๋ ์ด์ด์ ์ญ์ ํ๋ฅผ ์ํํฉ๋๋ค.
๋จผ์ , ์ ๋ ฅ ๋ ์ด์ด, self ๋ ์ด์ด, output ๋ ์ด์ด์ ๋ํ ํฌ์ธํฐ๋ฅผ ์ด๊ธฐํํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์, l.steps ๋ฒ ๋ฐ๋ณตํ๋ฉด์ ๊ฐ ์คํ ์์ ๋ค์์ ์ํํฉ๋๋ค.
์ ๋ ฅ ๋ ์ด์ด์ self ๋ ์ด์ด์ ์ถ๋ ฅ ๊ฐ์ ํฉ์ณ์ l.state์ ์ ์ฅํ ํ, ์ถ๋ ฅ ๋ ์ด์ด์ ์ญ์ ํ๋ฅผ ์ํํฉ๋๋ค.
๊ทธ ํ, self ๋ ์ด์ด์ ์ญ์ ํ๋ฅผ ์ํํ๊ณ , ์ด์ ์คํ ์ self ๋ ์ด์ด ์ ๋ฐ์ดํธ ๋ธํ๋ฅผ ํ์ฌ ์คํ ์ ์ ๋ ฅ ๋ ์ด์ด ์ ๋ฐ์ดํธ ๋ธํ๋ก ๋ณต์ฌํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก, ํ์ฌ ์คํ ์ ์ ๋ ฅ ๋ฐ์ดํฐ์ ๋ํ ์ญ์ ํ๋ฅผ ์ํํฉ๋๋ค.
์ค๋ช :
์ด ํจ์๋ CRNN ๋ ์ด์ด์ ์ญ์ ํ๋ฅผ ์ํํ๋ ํจ์๋ก, ๋คํธ์ํฌ๊ฐ ํ์ต ์ค์ธ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค.
l์ ์ญ์ ํ๋ฅผ ์ํํ ๋ ์ด์ด๋ฅผ ๋ํ๋ด๋ layer ๊ตฌ์กฐ์ฒด์ด๋ฉฐ, net์ ๋ ์ด์ด๋ฅผ ํฌํจํ๋ ๋คํธ์ํฌ๋ฅผ ๋ํ๋ด๋ network ๊ตฌ์กฐ์ฒด์ ๋๋ค.
์ด ํจ์๋ ๊ฐ ๋ ์ด์ด์ ์ถ๋ ฅ ๊ฐ์ ๊ณ์ฐํ๊ณ ๋ธํ ๊ฐ์ ์ ๋ฐ์ดํธํฉ๋๋ค.
update_crnn_layer
void update_crnn_layer(layer l, update_args a)
{
update_convolutional_layer(*(l.input_layer), a);
update_convolutional_layer(*(l.self_layer), a);
update_convolutional_layer(*(l.output_layer), a);
}
ํจ์ ์ด๋ฆ: update_crnn_layer
์ ๋ ฅ:
layer l: ์ ๋ฐ์ดํธํ CRNN ๋ ์ด์ด
update_args a: ์ ๋ฐ์ดํธ์ ์ฌ์ฉํ ์ธ์๋ค (learning rate, momentum ๋ฑ)
๋์:
์ฃผ์ด์ง ์ ๋ฐ์ดํธ ์ธ์๋ค์ ์ฌ์ฉํ์ฌ ์ ๋ ฅ์ผ๋ก ์ฃผ์ด์ง CRNN ๋ ์ด์ด์ input_layer, self_layer, output_layer๋ฅผ ๊ฐ๊ฐ ์ ๋ฐ์ดํธํ๋ ํจ์์ ๋๋ค.
update_convolutional_layer ํจ์๋ฅผ ํธ์ถํ์ฌ ๊ฐ ๋ ์ด์ด๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
์ค๋ช :
CRNN ๋ ์ด์ด๋ ์ ๋ ฅ ์ํ์ค๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ปจ๋ณผ๋ฃจ์ ๋ ์ด์ด์ RNN ๋ ์ด์ด์ ๊ฒฐํฉ์ ๋๋ค.
์ด ํจ์๋ ๊ทธ ์ค ์ปจ๋ณผ๋ฃจ์ ๋ ์ด์ด๋ฅผ ์ ๋ฐ์ดํธํ๋ ํจ์์ ๋๋ค.
์ด ํจ์๋ ์ ๋ ฅ์ผ๋ก ๋ฐ์ update_args๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ๋ ์ด์ด์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
๋จผ์ , input_layer, self_layer, output_layer ๊ฐ๊ฐ์ ๋ํด update_convolutional_layer ํจ์๋ฅผ ํธ์ถํ์ฌ ๊ทธ ๋ ์ด์ด์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
์ด ํจ์๋ ์ปจ๋ณผ๋ฃจ์ ๋ ์ด์ด์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฐ์ดํธํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ํจ์์ ๋๋ค.
make_crnn_layer
layer make_crnn_layer(int batch, int h, int w, int c, int hidden_filters, int output_filters, int steps, ACTIVATION activation, int batch_normalize)
{
fprintf(stderr, "CRNN Layer: %d x %d x %d image, %d filters\n", h,w,c,output_filters);
batch = batch / steps;
layer l = {0};
l.batch = batch;
l.type = CRNN;
l.steps = steps;
l.h = h;
l.w = w;
l.c = c;
l.out_h = h;
l.out_w = w;
l.out_c = output_filters;
l.inputs = h*w*c;
l.hidden = h * w * hidden_filters;
l.outputs = l.out_h * l.out_w * l.out_c;
l.state = calloc(l.hidden*batch*(steps+1), sizeof(float));
l.input_layer = malloc(sizeof(layer));
fprintf(stderr, "\t\t");
*(l.input_layer) = make_convolutional_layer(batch*steps, h, w, c, hidden_filters, 1, 3, 1, 1, activation, batch_normalize, 0, 0, 0);
l.input_layer->batch = batch;
l.self_layer = malloc(sizeof(layer));
fprintf(stderr, "\t\t");
*(l.self_layer) = make_convolutional_layer(batch*steps, h, w, hidden_filters, hidden_filters, 1, 3, 1, 1, activation, batch_normalize, 0, 0, 0);
l.self_layer->batch = batch;
l.output_layer = malloc(sizeof(layer));
fprintf(stderr, "\t\t");
*(l.output_layer) = make_convolutional_layer(batch*steps, h, w, hidden_filters, output_filters, 1, 3, 1, 1, activation, batch_normalize, 0, 0, 0);
l.output_layer->batch = batch;
l.output = l.output_layer->output;
l.delta = l.output_layer->delta;
l.forward = forward_crnn_layer;
l.backward = backward_crnn_layer;
l.update = update_crnn_layer;
return l;
}
ํจ์ ์ด๋ฆ: make_crnn_layer
์ ๋ ฅ:
int batch: ๋ฐฐ์น ํฌ๊ธฐ
int h: ์ ๋ ฅ ์ด๋ฏธ์ง ๋์ด
int w: ์ ๋ ฅ ์ด๋ฏธ์ง ๋๋น
int c: ์ ๋ ฅ ์ด๋ฏธ์ง ์ฑ๋ ์
int hidden_filters: ์จ๊ฒจ์ง ๋ ์ด์ด์์ ์ฌ์ฉ๋๋ ํํฐ ์
int output_filters: ์ถ๋ ฅ ๋ ์ด์ด์์ ์ฌ์ฉ๋๋ ํํฐ ์
int steps: ์ํ์ค ๊ธธ์ด (์คํ ์)
ACTIVATION activation: ํ์ฑํ ํจ์ ์ ํ
int batch_normalize: ๋ฐฐ์น ์ ๊ทํ ์ฌ๋ถ
๋์:
CRNN ๋ ์ด์ด๋ฅผ ๋ง๋ค๊ณ ์ด๊ธฐํํฉ๋๋ค.
์ค๋ช :
์ด ํจ์๋ ์ ๋ ฅ ์ด๋ฏธ์ง์ ๋์ด, ๋๋น, ์ฑ๋ ์ ๋ฐ ์ํ์ค ๊ธธ์ด์ ๊ฐ์ ์ธ์๋ฅผ ์ฌ์ฉํ์ฌ CRNN(Convolutional Recurrent Neural Network) ๋ ์ด์ด๋ฅผ ๋ง๋ญ๋๋ค.
์ด ๋ ์ด์ด๋ ์จ๊ฒจ์ง ๋ ์ด์ด์ ์ถ๋ ฅ ๋ ์ด์ด ๊ฐ๊ฐ์ ๋ํด 3x3 ์ปค๋๊ณผ ๊ฐ์ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ 1D ์ปจ๋ณผ๋ฃจ์ ๋ ์ด์ด๋ฅผ ํฌํจํฉ๋๋ค.
์ด ํจ์๋ ์ด๋ฌํ ๋ ์ด์ด๋ฅผ ๋ง๋ค๊ณ ์ด๊ธฐํํ ํ CRNN ๋ ์ด์ด๋ฅผ ๋ฐํํฉ๋๋ค.
Last updated
Was this helpful?