작성
·
180
0
안녕하세요. 토이 프로젝트로 이미지 안의 text를 감지하는 모델 중 하나인 EAST에 대해서 코드 수행을 하려고 했는데
누군가 짜놓은 코드 기반으로 하다보니, 코드 내부에서 모델 구성하는 부분에서 궁금한 점이 있어서요!
모델의 시작은 resnet50 입력부터 시작하는 것 같습니다. 실제 summary에서도 그렇게 나오고, 이 출력은 Unet 기반으로 피처를 concat 하는 형태로 가져가서 마지막에 regression을 하게 됩니다
모델 resnet50 입력에 input_tensor 파라미터를 통해서 input_image라고 지정을 하게 되어서 shape는 아래 캡쳐한 것처럼 (None, None, None, 3)라고 나온 것 같습니다
그런데 코드 마지막에 최종 모델 API에서는 입력에
overly_small_text_region_training_mask, text_region_boundary_training_mask, target_score_map
을 추가로 지정하는데, 해당 입력 텐서 3개는 전혀 모델 입력으로 들어가지 않는 것 아닌가요?
감사합니다
class EAST_model:
def __init__(self, input_size=512):
input_image = Input(shape=(None, None, 3), name='input_image')
overly_small_text_region_training_mask = Input(shape=(None, None, 1), name='overly_small_text_region_training_mask')
text_region_boundary_training_mask = Input(shape=(None, None, 1), name='text_region_boundary_training_mask')
target_score_map = Input(shape=(None, None, 1), name='target_score_map')
resnet = ResNet50(input_tensor=input_image, weights='imagenet', include_top=False, pooling=None)
# print(resnet.summary())
x = resnet.get_layer('conv5_block3_out').output
x = Lambda(resize_bilinear, name='resize_1')(x)
x = concatenate([x, resnet.get_layer('conv4_block6_out').output], axis=3)
x = Conv2D(128, (1, 1), padding='same', kernel_regularizer=regularizers.l2(1e-5))(x)
x = BatchNormalization(momentum=0.997, epsilon=1e-5, scale=True)(x)
x = Activation('relu')(x)
x = Conv2D(128, (3, 3), padding='same', kernel_regularizer=regularizers.l2(1e-5))(x)
x = BatchNormalization(momentum=0.997, epsilon=1e-5, scale=True)(x)
x = Activation('relu')(x)
x = Lambda(resize_bilinear, name='resize_2')(x)
x = concatenate([x, resnet.get_layer('conv3_block4_out').output], axis=3)
x = Conv2D(64, (1, 1), padding='same', kernel_regularizer=regularizers.l2(1e-5))(x)
x = BatchNormalization(momentum=0.997, epsilon=1e-5, scale=True)(x)
x = Activation('relu')(x)
x = Conv2D(64, (3, 3), padding='same', kernel_regularizer=regularizers.l2(1e-5))(x)
x = BatchNormalization(momentum=0.997, epsilon=1e-5, scale=True)(x)
x = Activation('relu')(x)
x = Lambda(resize_bilinear, name='resize_3')(x)
#x = concatenate([x, ZeroPadding2D(((1, 0),(1, 0)))(resnet.get_layer('conv2_block3_out').output)], axis=3)
x = concatenate([x, resnet.get_layer('conv2_block3_out').output], axis=3)
x = Conv2D(32, (1, 1), padding='same', kernel_regularizer=regularizers.l2(1e-5))(x)
x = BatchNormalization(momentum=0.997, epsilon=1e-5, scale=True)(x)
x = Activation('relu')(x)
x = Conv2D(32, (3, 3), padding='same', kernel_regularizer=regularizers.l2(1e-5))(x)
x = BatchNormalization(momentum=0.997, epsilon=1e-5, scale=True)(x)
x = Activation('relu')(x)
x = Conv2D(32, (3, 3), padding='same', kernel_regularizer=regularizers.l2(1e-5))(x)
x = BatchNormalization(momentum=0.997, epsilon=1e-5, scale=True)(x)
x = Activation('relu')(x)
pred_score_map = Conv2D(1, (1, 1), activation=tf.nn.sigmoid, name='pred_score_map')(x)
rbox_geo_map = Conv2D(4, (1, 1), activation=tf.nn.sigmoid, name='rbox_geo_map')(x)
rbox_geo_map = Lambda(lambda x: x * input_size)(rbox_geo_map)
angle_map = Conv2D(1, (1, 1), activation=tf.nn.sigmoid, name='rbox_angle_map')(x)
angle_map = Lambda(lambda x: (x - 0.5) * np.pi / 2)(angle_map)
pred_geo_map = concatenate([rbox_geo_map, angle_map], axis=3, name='pred_geo_map')
model = Model(inputs=[input_image, overly_small_text_region_training_mask, text_region_boundary_training_mask, target_score_map], outputs=[pred_score_map, pred_geo_map])
답변 1
0
아, 다시 코드를 보니 loss 정의에서 위 3개 텐서가 사용하더라구요
model.compile(loss=[dice_loss(east.overly_small_text_region_training_mask, east.text_region_boundary_training_mask, score_map_loss_weight, small_text_weight),
rbox_loss(east.overly_small_text_region_training_mask, east.text_region_boundary_training_mask, small_text_weight, east.target_score_map)],
loss_weights=[1., 1.],
optimizer=opt)
각 배치마다 저 3개의 값이 다르고, 이를 loss 때 계산 용도로 사용하려고 전달하는 것 같습니다. 실제 모델에서 사용하지 않지만, 저렇게 다른 용도를 위해서 Model.input 파라미터 입력으로 전달해주는 경우도 종종 있나요?
감사합니다
네, 충분히 그런 경우가 있을 수 있습니다.
감사합니다.