def _comp_feature_importance_weight(self, class_id): if not isinstance(class_id, list): class_id = [class_id] with tf.name_scope('feature_weight'): self._feature_w_list = [] for idx, cid in enumerate(class_id): # 將輸出轉為指定類別為1,其餘為0,shape為(nclass, 1)的one hot 形式 one_hot = tf.sparse_to_dense([[cid, 0]], [self._nclass, 1], 1.0) # _out_act: 每個類別的激活值,reshape to (1, nclass) out_act = tf.reshape(self._out_act, [1, self._nclass]) #class_act(1, 1) = _out_act(1, nclass) * one_hot(nclass, 1),代表僅保留該類別的激活值 class_act = tf.matmul(out_act, one_hot, name='class_act_{}'.format(idx)) #該類別的激活值(class_act)對特徵圖的每個像素(_conv_out)求導,con_out是conv5_4的卷積結果(最後一層卷積特徵圖) feature_grad = tf.gradients(class_act, self._conv_out, name='grad_{}'.format(idx)) #將feature_grad刪除第0維度,shape會和con_out的shape一樣,con_out中每張特徵圖的每個像素值,都有對應的導數(權值)。 feature_grad = tf.squeeze(tf.convert_to_tensor(feature_grad), axis=0) #feature_w: 對feature_grad做GAP,即針對特徵圖中每個像素值的導數(加權值)取平均,得一張特徵圖一個權值 feature_w = global_avg_pool(feature_grad, name='feature_w_{}'.format(idx)) self._feature_w_list.append(feature_w)
def _create_model(self): input_im = self.model_input[0] keep_prob = self.model_input[1] conv_out = self._create_conv(input_im) init_b = tf.truncated_normal_initializer(stddev=0.01) conv_cam = conv(conv_out, 3, 1024, 'conv_cam', nl=tf.nn.relu, wd=0.01, init_b=init_b) gap = global_avg_pool(conv_cam) dropout_gap = dropout(gap, keep_prob, self.is_training) with tf.variable_scope('cam'): init = tf.truncated_normal_initializer(stddev=0.01) #fc_w: shape is (1024, nclass) fc_w = new_weights( 'weights', 1, [gap.get_shape().as_list()[-1], self._num_class], initializer=init, wd=0.01) fc_cam = tf.matmul(dropout_gap, fc_w, name='output') self.output = tf.identity(fc_cam, 'model_output') self.prediction = tf.argmax(fc_cam, name='pre_label', axis=-1) self.prediction_pro = tf.nn.softmax(fc_cam, name='pre_pro') if self._inspect_class is not None: with tf.name_scope('classmap'): self.get_classmap(self._inspect_class, conv_cam, input_im)
def setup_graph(self): self.input_im = self._vis_model.layer['input'] self._out_act = global_avg_pool(self._vis_model.layer['output']) self._conv_out = self._vis_model.layer['conv_out'] self._nclass = self._out_act.shape.as_list()[-1] self.pre_label = tf.nn.top_k(tf.nn.softmax(self._out_act), k=5, sorted=True)
def _create_model(self, image_a, image_b): keep_prob = 1 self._vis_model.create_model([image_a, image_b, keep_prob]) self.input_im_a = self._vis_model.layer['input_a'] self.input_im_b = self._vis_model.layer['input_b'] self._out_act = global_avg_pool(self._vis_model.layer['output']) self.pre_label = tf.nn.top_k( tf.nn.softmax(self._out_act), k=5, sorted=True)
def setup_graph(self): self.input_im = self._vis_model.layer['input'] # layer['output']: 是最後一個1*1 conv的輸出(命名為fc8),其深度為nclass # _out_act: 每個類別的激活值,用以代表每個類別的特徵圖 self._out_act = global_avg_pool(self._vis_model.layer['output']) # layer['conv_out']: 是特徵抽取之捲基層的最後一層輸出(為'conv5_4'之輸出) self._conv_out = self._vis_model.layer['conv_out'] self._nclass = self._out_act.shape.as_list()[-1] #pre_label: 為所有類別的激活值中,前5大的激活值與對應的類別號碼,並從大致小排序 self.pre_label = tf.nn.top_k(tf.nn.softmax(self._out_act), k=5, sorted=True)
def _create_model(self): inputs = self._input_dict['input'] conv_out = self._create_conv(inputs) # init_b = tf.truncated_normal_initializer(stddev=0.01) # conv_gap = conv(conv_out, 3, self._n_class, 'conv_gap', # nl=tf.nn.relu, wd=0, init_b=init_b) gap = global_avg_pool(conv_out) self.layer['logits'] = gap self.layer['feature'] = conv_out self.layer['pred'] = tf.argmax(gap, name='pred', axis=-1) self.layer['prob'] = tf.nn.softmax(gap, name='prob')
def _create_model(self, image): keep_prob = 1 self._vis_model.create_model([image, keep_prob]) self.input_im = self._vis_model.layer['input'] #VGG19_FCN: 沒有全連接層,透過 4096個7*7*512 => 4096個1*1*4096 => 1000個1*1*4096 取代 #layer['output']: 一個四維的tensor #_out_act: 為VGG19_FCN之輸出層(同樣命名為fc8)經過GAP的activate值 => 1000*1 self._out_act = global_avg_pool(self._vis_model.layer['output']) #pre_label: 透過softmax將_out_act轉成機率型態,緊保留前k個機率最大的分類結果,並由大到小排序。 self.pre_label = tf.nn.top_k(tf.nn.softmax(self._out_act), k=5, sorted=True)
def _comp_feature_importance_weight(self, class_id): if not isinstance(class_id, list): class_id = [class_id] with tf.name_scope('feature_weight'): self._feature_w_list = [] for idx, cid in enumerate(class_id): one_hot = tf.sparse_to_dense([[cid, 0]], [self._nclass, 1], 1.0) out_act = tf.reshape(self._out_act, [1, self._nclass]) class_act = tf.matmul(out_act, one_hot, name='class_act_{}'.format(idx)) feature_grad = tf.gradients(class_act, self._conv_out, name='grad_{}'.format(idx)) feature_grad = tf.squeeze(tf.convert_to_tensor(feature_grad), axis=0) feature_w = global_avg_pool(feature_grad, name='feature_w_{}'.format(idx)) self._feature_w_list.append(feature_w)
def _create_model(self): with tf.name_scope('input'): input_im = self.model_input[0] keep_prob = self.model_input[1] if self._is_rescale: input_im =\ resize_tensor_image_with_smallest_side(input_im, 224) self.layer['input'] = input_im red, green, blue = tf.split(axis=3, num_or_size_splits=3, value=input_im) input_bgr = tf.concat(axis=3, values=[ blue - MEAN[0], green - MEAN[1], red - MEAN[2], ]) data_dict = {} if self._is_load: data_dict = np.load(self._pre_train_path, encoding='latin1').item() inception5b = self._create_conv(input_bgr, data_dict) gap = global_avg_pool(inception5b) gap_dropout = dropout(gap, keep_prob, self.is_training) fc1 = fc(gap_dropout, 1000, 'loss3_classifier', data_dict=data_dict) self.layer['conv_out'] = inception5b self.layer['output'] = fc1 self.layer['class_prob'] = tf.nn.softmax(fc1, name='class_prob') self.layer['pre_prob'] = tf.reduce_max(self.layer['class_prob'], axis=-1, name='pre_prob') self.layer['prediction'] = tf.argmax(self.layer['output'], axis=-1)
def _create_conv(inputs, data_dict): arg_scope = tf.contrib.framework.arg_scope with arg_scope([conv], trainable=False, data_dict=data_dict, nl=tf.nn.relu): conv1 = conv(inputs, 7, 64, name='conv1_7x7_s2', stride=2) padding1 = tf.constant([[0, 0], [0, 1], [0, 1], [0, 0]]) conv1_pad = tf.pad(conv1, padding1, 'CONSTANT') pool1 = max_pool(conv1_pad, 'pool1', padding='VALID', filter_size=3, stride=2) pool1_lrn = tf.nn.local_response_normalization(pool1, depth_radius=2, alpha=2e-05, beta=0.75, name='pool1_lrn') conv2_reduce = conv(pool1_lrn, 1, 64, name='conv2_3x3_reduce') conv2 = conv(conv2_reduce, 3, 192, name='conv2_3x3') padding2 = tf.constant([[0, 0], [0, 1], [0, 1], [0, 0]]) conv2_pad = tf.pad(conv2, padding1, 'CONSTANT') pool2 = max_pool(conv2_pad, 'pool2', padding='VALID', filter_size=3, stride=2) pool2_lrn = tf.nn.local_response_normalization(pool2, depth_radius=2, alpha=2e-05, beta=0.75, name='pool2_lrn') with arg_scope([inception_layer], trainable=False, data_dict=data_dict): inception3a = inception_layer(pool2_lrn, 64, 96, 128, 16, 32, 32, name='inception_3a') inception3b = inception_layer(inception3a, 128, 128, 192, 32, 96, 64, name='inception_3b') pool3 = max_pool(inception3b, 'pool3', padding='SAME', filter_size=3, stride=2) inception4a = inception_layer(pool3, 192, 96, 208, 16, 48, 64, name='inception_4a') inception4b = inception_layer(inception4a, 160, 112, 224, 24, 64, 64, name='inception_4b') inception4c = inception_layer(inception4b, 128, 128, 256, 24, 64, 64, name='inception_4c') inception4d = inception_layer(inception4c, 112, 144, 288, 32, 64, 64, name='inception_4d') inception4e = inception_layer(inception4d, 256, 160, 320, 32, 128, 128, name='inception_4e') pool4 = max_pool(inception4e, 'pool4', padding='SAME', filter_size=3, stride=2) inception5a = inception_layer(pool4, 256, 160, 320, 32, 128, 128, name='inception_5a') inception5b = inception_layer(inception5a, 384, 192, 384, 48, 128, 128, name='inception_5b') pool5 = global_avg_pool(inception5b, name='global_avg_pool') return pool5