cost_layer
Loss๋ฅผ ๊ตฌํ๊ธฐ ์ํ layer์ ๋๋ค.
COST_TYPE
typedef enum{
SSE, MASKED, L1, SEG, SMOOTH,WGAN
} COST_TYPE;
์ ์ฝ๋๋ COST_TYPE๋ผ๋ ์ด๊ฑฐํ(enum)์ ์ ์ํ๋ ์ฝ๋์ ๋๋ค. COST_TYPE์ ๋คํธ์ํฌ์ ์์ค ํจ์(loss function)๋ฅผ ์ง์ ํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
์ด ์ด๊ฑฐํ์ ๋ค์ฏ ๊ฐ์ง์ ์์(constant)๋ฅผ ์ ์ํ๊ณ ์์ต๋๋ค:
SSE : ํ๊ท ์ ๊ณฑ ์ค์ฐจ(Mean Squared Error, MSE) ์์ค ํจ์๋ฅผ ๋ํ๋ ๋๋ค. ์ค์ ๊ฐ๊ณผ ์์ธก ๊ฐ์ ์ฐจ์ด๋ฅผ ์ ๊ณฑํ ํ ๋ชจ๋ ์ ๋ ฅ์ ๋ํด ํ๊ท ์ ์ทจํ ๊ฐ์ผ๋ก, ์์ธก์ด ์ ํํ ์๋ก ๊ฐ์ด ์์์ง๋๋ค.
MASKED : ๋ง์คํฌ(mask)๋ฅผ ์ ์ฉํ ํ๊ท ์ ๊ณฑ ์ค์ฐจ ์์ค ํจ์์ ๋๋ค. ๋ง์คํฌ๋ ์ผ๋ถ ์ ๋ ฅ์ ๋ฌด์ํ๊ณ ์์ค์ ๊ณ์ฐํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
L1 : ์ ๋ ์ค์ฐจ(Absolute Error) ์์ค ํจ์๋ฅผ ๋ํ๋ ๋๋ค. ์ค์ ๊ฐ๊ณผ ์์ธก ๊ฐ์ ์ฐจ์ด์ ์ ๋๊ฐ์ ๋ํด ๋ชจ๋ ์ ๋ ฅ์ ๋ํด ํ๊ท ์ ์ทจํ ๊ฐ์ผ๋ก, ์์ธก์ด ์ ํํ ์๋ก ๊ฐ์ด ์์์ง๋๋ค.
SEG : ์ธ๊ทธ๋ฉํ ์ด์ (segmentation) ๋ฌธ์ ์ ์ฌ์ฉ๋๋ ๊ต์ฐจ ์ํธ๋กํผ(Cross-Entropy) ์์ค ํจ์์ ๋๋ค. ์ ๋ ฅ ์ด๋ฏธ์ง์ ๊ฐ ํฝ์ ์ด ํด๋์ค(class)์ ์ํ ํ๋ฅ ์ ์์ธกํ๊ณ , ์ด ์์ธก ๊ฐ๊ณผ ์ค์ ํด๋์ค ๊ฐ์ ์ฐจ์ด์ ๋ํด ์์ค์ ๊ณ์ฐํฉ๋๋ค.
SMOOTH : ์ธ๊ทธ๋ฉํ ์ด์ ๋ฌธ์ ์ ์ฌ์ฉ๋๋ ์ค๋ฌด๋ฉ(smoothing)๋ ๊ต์ฐจ ์ํธ๋กํผ ์์ค ํจ์์ ๋๋ค. SEG์ ์ ์ฌํ์ง๋ง, ์์ธก๊ฐ๊ณผ ์ค์ ๊ฐ ๊ฐ์ ์ค์ฐจ๋ฅผ ํํํ(smoothing)ํ์ฌ ์ธ๊ทธ๋ฉํ ์ด์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ค ๋ถ๋๋ฝ๊ฒ ๋ง๋ญ๋๋ค.
WGAN : ์์ฑ์ ์ ๋ ์ ๊ฒฝ๋ง(Generative Adversarial Network, GAN)์์ ์ฌ์ฉ๋๋ ์์ค ํจ์์ธ Wasserstein GAN ์์ค ํจ์์ ๋๋ค. GAN์ ์ด๋ฏธ์ง ์์ฑ์ ํ์ฉ๋๋ ๋ฅ๋ฌ๋ ๋ชจ๋ธ๋ก, WGAN ์์ค ํจ์๋ ์์ฑ๋ ์ด๋ฏธ์ง์ ์ค์ ์ด๋ฏธ์ง ๊ฐ์ ๊ฑฐ๋ฆฌ๋ฅผ ์ต์ํํ๋ ๋ฐฉ์์ผ๋ก ๋ชจ๋ธ์ ํ์ตํฉ๋๋ค.
get_cost_type
COST_TYPE get_cost_type(char *s)
{
if (strcmp(s, "seg")==0) return SEG;
if (strcmp(s, "sse")==0) return SSE;
if (strcmp(s, "masked")==0) return MASKED;
if (strcmp(s, "smooth")==0) return SMOOTH;
if (strcmp(s, "L1")==0) return L1;
if (strcmp(s, "wgan")==0) return WGAN;
fprintf(stderr, "Couldn't find cost type %s, going with SSE\n", s);
return SSE;
}
ํจ์ ์ด๋ฆ: get_cost_type
์ ๋ ฅ:
s: ๋ฌธ์์ด ํฌ์ธํฐ
๋์:
์ ๋ ฅ๋ ๋ฌธ์์ด s์ COST_TYPE ์ด๊ฑฐํ ์์๋ฅผ ๋น๊ตํ์ฌ ์ผ์นํ๋ COST_TYPE์ ๋ฐํํฉ๋๋ค.
์ ๋ ฅ๋ ๋ฌธ์์ด๊ณผ ์ผ์นํ๋ COST_TYPE์ด ์์ผ๋ฉด "Couldn't find cost type %s, going with SSE" ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ SSE๋ฅผ ๋ฐํํฉ๋๋ค.
์ค๋ช :
get_cost_type ํจ์๋ ๋ฌธ์์ด s๋ฅผ ์ ๋ ฅ์ผ๋ก ๋ฐ์ ์ด์ ๋์ํ๋ COST_TYPE์ ๋ฐํํฉ๋๋ค.
์ ๋ ฅ๋ ๋ฌธ์์ด s๋ฅผ SEG, SSE, MASKED, SMOOTH, L1, WGAN๊ณผ ์ฐจ๋ก๋๋ก ๋น๊ตํ๋ฉด์ ์ผ์นํ๋ COST_TYPE ์์๋ฅผ ๋ฐํํฉ๋๋ค.
์ผ์นํ๋ ๋ฌธ์์ด์ด ์์ ๊ฒฝ์ฐ fprintf ํจ์๋ฅผ ์ฌ์ฉํ์ฌ "Couldn't find cost type %s, going with SSE" ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ SSE๋ฅผ ๋ฐํํฉ๋๋ค.
ํจ์๊ฐ ๋ฐํํ๋ ๊ฐ์ COST_TYPE ์ด๊ฑฐํ ์์์ ๋๋ค.
get_cost_string
char *get_cost_string(COST_TYPE a)
{
switch(a){
case SEG:
return "seg";
case SSE:
return "sse";
case MASKED:
return "masked";
case SMOOTH:
return "smooth";
case L1:
return "L1";
case WGAN:
return "wgan";
}
return "sse";
}
ํจ์ ์ด๋ฆ: get_cost_string
์ ๋ ฅ:
a: COST_TYPE ํ์ ์ ๋ณ์
๋์:
a์ ํด๋นํ๋ COST_TYPE์ ๋ํ ๋ฌธ์์ด์ ๋ฐํํ๋ค.
์ค๋ช :
์ ๋ ฅ์ผ๋ก ๋ฐ์ COST_TYPE a์ ํด๋นํ๋ ๋ฌธ์์ด์ ๋ฐํํ๋ ํจ์์ด๋ค.
switch ๋ฌธ์ ์ฌ์ฉํ์ฌ a๊ฐ ๊ฐ๊ฐ์ COST_TYPE์ ํด๋นํ๋ ๊ฒฝ์ฐ์ ํด๋นํ๋ ๋ฌธ์์ด์ ๋ฐํํ๋ค.
๋ง์ฝ a๊ฐ ์ด๋ ํ COST_TYPE์๋ ํด๋นํ์ง ์๋ ๊ฒฝ์ฐ "sse" ๋ฌธ์์ด์ ๋ฐํํ๋ค.
forward_cost_layer
void forward_cost_layer(cost_layer l, network net)
{
if (!net.truth) return;
if(l.cost_type == MASKED){
int i;
for(i = 0; i < l.batch*l.inputs; ++i){
if(net.truth[i] == SECRET_NUM) net.input[i] = SECRET_NUM;
}
}
if(l.cost_type == SMOOTH){
smooth_l1_cpu(l.batch*l.inputs, net.input, net.truth, l.delta, l.output);
}else if(l.cost_type == L1){
l1_cpu(l.batch*l.inputs, net.input, net.truth, l.delta, l.output);
} else {
l2_cpu(l.batch*l.inputs, net.input, net.truth, l.delta, l.output);
}
l.cost[0] = sum_array(l.output, l.batch*l.inputs);
}
ํจ์ ์ด๋ฆ: forward_cost_layer
์ ๋ ฅ:
cost_layer l: ๋น์ฉ ๊ณ์ฐ ๋ ์ด์ด ๊ตฌ์กฐ์ฒด
network net: ์ ๊ฒฝ๋ง ๊ตฌ์กฐ์ฒด
๋์:
net.truth์ด ์กด์ฌํ๋ฉด ์คํ
l.cost_type์ด MASKED์ผ ๊ฒฝ์ฐ, SECRET_NUM์ผ๋ก ํ์๋ ๊ฐ์ด ์๋ ์์น๋ net.input ๊ฐ๋ SECRET_NUM์ผ๋ก ๋ณ๊ฒฝ
l.cost_type์ด SMOOTH์ผ ๊ฒฝ์ฐ, smooth L1 ํจ์๋ฅผ ์ด์ฉํ์ฌ ์์ธก ๊ฐ๊ณผ ์ค์ ๊ฐ์ ์ฐจ์ด๋ฅผ ๊ณ์ฐํ์ฌ l.delta์ l.output์ ์ ์ฅ
l.cost_type์ด L1์ผ ๊ฒฝ์ฐ, L1 ํจ์๋ฅผ ์ด์ฉํ์ฌ ์์ธก ๊ฐ๊ณผ ์ค์ ๊ฐ์ ์ฐจ์ด๋ฅผ ๊ณ์ฐํ์ฌ l.delta์ l.output์ ์ ์ฅ
l.cost_type์ด ๊ทธ ์ธ์ผ ๊ฒฝ์ฐ, L2 ํจ์๋ฅผ ์ด์ฉํ์ฌ ์์ธก ๊ฐ๊ณผ ์ค์ ๊ฐ์ ์ฐจ์ด๋ฅผ ๊ณ์ฐํ์ฌ l.delta์ l.output์ ์ ์ฅ
l.output์ ๋ชจ๋ ์์์ ํฉ์ l.cost[0]์ ์ ์ฅ
์ค๋ช :
๋น์ฉ ๊ณ์ฐ ๋ ์ด์ด๋ ์ ๊ฒฝ๋ง์ ์์ธก ๊ฒฐ๊ณผ์ ์ค์ ๊ฒฐ๊ณผ์ ์ฐจ์ด๋ฅผ ๊ณ์ฐํ์ฌ ๋น์ฉ์ ๊ตฌํ๋ ์ญํ ์ ํฉ๋๋ค.
์ด ํจ์๋ ์ฃผ์ด์ง ๋น์ฉ ๊ณ์ฐ ๋ ์ด์ด์ ์ ๊ฒฝ๋ง์ ์ด์ฉํ์ฌ ๋น์ฉ์ ๊ณ์ฐํ๊ณ , ๊ณ์ฐ๋ ๋น์ฉ์ l.cost[0]์ ์ ์ฅํฉ๋๋ค.
๋ํ, l.cost_type์ ๋ฐ๋ผ์ ์์ธก ๊ฐ๊ณผ ์ค์ ๊ฐ์ ์ฐจ์ด๋ฅผ ๊ณ์ฐํ๋ ํจ์๋ฅผ ํธ์ถํ์ฌ l.delta์ l.output์ ์ ์ฅํฉ๋๋ค.
์ด๋, l.cost_type์ด MASKED์ผ ๊ฒฝ์ฐ, SECRET_NUM์ผ๋ก ํ์๋ ๊ฐ์ด ์๋ ์์น๋ net.input ๊ฐ๋ SECRET_NUM์ผ๋ก ๋ณ๊ฒฝํ์ฌ ๋น์ฉ ๊ณ์ฐ์์ ์ ์ธํฉ๋๋ค.
.
backward_cost_layer
void backward_cost_layer(const cost_layer l, network net)
{
axpy_cpu(l.batch*l.inputs, l.scale, l.delta, 1, net.delta, 1);
}
ํจ์ ์ด๋ฆ: backward_cost_layer
์ ๋ ฅ:
cost_layer l
network net
๋์:
cost_layer์ gradient๋ฅผ ๊ณ์ฐํ๊ณ , ์ด๋ฅผ network์ delta๊ฐ์ ๋ํด์ค๋ค.
์ด ๋, l.scale์ gradient์ ํฌ๊ธฐ๋ฅผ ์ ์ดํ๊ธฐ ์ํ ์ค์ผ์ผ๋ง ์ธ์์ด๋ค.
์ค๋ช :
cost_layer์ gradient๋ delta ๋ฐฐ์ด์ ์ ์ฅ๋๋ค.
axpy_cpu ํจ์๋ฅผ ํตํด net.delta ๋ฐฐ์ด์ l.delta ๋ฐฐ์ด์ l.scale๋งํผ ์ค์ผ์ผ๋งํ์ฌ ๋ํด์ค๋ค.
์ด ๋, ๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ l.batch*l.inputs์ด๋ค.
์ฆ, cost_layer๋ฅผ ํตํด ๊ตฌํ gradient๋ network์ ๋ค์ layer๋ก ์ ๋ฌ๋๋ฉฐ, ์ดํ์ backward propagation์ด ์ด์ด์ ธ์ gradient๊ฐ ์ญ์ ํ๋๊ฒ ๋๋ค.
resize_cost_layer
void resize_cost_layer(cost_layer *l, int inputs)
{
l->inputs = inputs;
l->outputs = inputs;
l->delta = realloc(l->delta, inputs*l->batch*sizeof(float));
l->output = realloc(l->output, inputs*l->batch*sizeof(float));
}
ํจ์ ์ด๋ฆ: resize_cost_layer
์ ๋ ฅ:
l: cost_layer ๊ตฌ์กฐ์ฒด ํฌ์ธํฐ
inputs: int
๋์:
cost_layer ๊ตฌ์กฐ์ฒด ํฌ์ธํฐ l์ inputs์ outputs ๋ฉค๋ฒ ๋ณ์๋ฅผ ์ ๋ ฅ๊ฐ์ผ๋ก ๋ณ๊ฒฝํ๊ณ , delta์ output ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ realloc ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ฌํ ๋นํ๋ค.
์ค๋ช :
ํจ์๋ cost_layer ๊ตฌ์กฐ์ฒด๋ฅผ ๋ฐ์์ ํด๋น ๊ตฌ์กฐ์ฒด์ ๋ฉค๋ฒ ๋ณ์๋ฅผ ์กฐ์ ํ๋ ์ญํ ์ ํ๋ค.
l์ inputs์ outputs ๋ฉค๋ฒ ๋ณ์๋ฅผ ์ ๋ ฅ๊ฐ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
realloc ํจ์๋ฅผ ์ฌ์ฉํ์ฌ l->delta ๋ฐฐ์ด๊ณผ l->output ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ inputsl->batchsizeof(float)์ผ๋ก ์ฌํ ๋นํ๋ค.
์ด ํจ์๋ resize_network ํจ์์์ ํธ์ถ๋๋ฉฐ, ์ ๊ฒฝ๋ง์ ์ฌ์กฐ์ ํ ๋ cost_layer๋ ํจ๊ป ์กฐ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ํ์ํ๋ค.
make_cost_layer
cost_layer make_cost_layer(int batch, int inputs, COST_TYPE cost_type, float scale)
{
fprintf(stderr, "cost %4d\n", inputs);
cost_layer l = {0};
l.type = COST;
l.scale = scale;
l.batch = batch;
l.inputs = inputs;
l.outputs = inputs;
l.cost_type = cost_type;
l.delta = calloc(inputs*batch, sizeof(float));
l.output = calloc(inputs*batch, sizeof(float));
l.cost = calloc(1, sizeof(float));
l.forward = forward_cost_layer;
l.backward = backward_cost_layer;
return l;
}
ํจ์ ์ด๋ฆ: make_cost_layer
์ ๋ ฅ:
int batch: batch size
int inputs: layer์ input dimension
COST_TYPE cost_type: cost function type
float scale: cost์ ํฌ๊ธฐ ์กฐ์ ์ ์ํ ์ค์ผ์ผ ๊ฐ
๋์:
cost_layer ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ํ๋๊ฐ๋ค์ ์ด๊ธฐํํ๋ค.
์ ๋ ฅ๋ฐ์ cost_type์ ๋ฐ๋ผ์ l.cost_type์ ์ค์ ํ๋ค.
l.delta, l.output, l.cost ๋ฐฐ์ด์ ์ด๊ธฐํํ๋ค.
forward์ backward ํจ์๋ฅผ ์ค์ ํ๋ค.
์ค๋ช :
์ด ํจ์๋ cost layer๋ฅผ ์์ฑํ๋ ํจ์๋ก, ์ ๋ ฅ๊ฐ๋ค์ ๋ฐ์์ cost layer์ ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ด๊ธฐํํ๋ ์ญํ ์ ํ๋ค. ์ด ํจ์๋ฅผ ํตํด์ ์์ฑ๋ cost layer๋ neural network์์ ์ฌ์ฉ๋๋ค.
Last updated
Was this helpful?