def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): '''data generator for fit_generator''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i==0: np.random.shuffle(annotation_lines) image, box = get_random_data(annotation_lines[i], input_shape, random=True) image_data.append(image) box_data.append(box) i = (i+1) % n image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) yield [image_data, *y_true], np.zeros(batch_size)
def bottleneck_generator(annotation_lines, batch_size, input_shape, anchors, num_classes, bottlenecks): n = len(annotation_lines) i = 0 while True: box_data = [] b0=np.zeros((batch_size,bottlenecks[0].shape[1],bottlenecks[0].shape[2],bottlenecks[0].shape[3])) b1=np.zeros((batch_size,bottlenecks[1].shape[1],bottlenecks[1].shape[2],bottlenecks[1].shape[3])) b2=np.zeros((batch_size,bottlenecks[2].shape[1],bottlenecks[2].shape[2],bottlenecks[2].shape[3])) for b in range(batch_size): _, box = get_random_data(annotation_lines[i], input_shape, random=False, proc_img=False) box_data.append(box) b0[b]=bottlenecks[0][i] b1[b]=bottlenecks[1][i] b2[b]=bottlenecks[2][i] i = (i+1) % n box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) yield [b0, b1, b2, *y_true], np.zeros(batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): '''data generator for fit_generator''' '''数据生成器 @param annotations_lines 训练样本,每行形如以下格式:img_file 6,1,314,262,19 40,97,121,411,4 137,36,169,109,14 180,36,216,104,14 96,39,123,103,14 @param batch_size 批大小,32 @param input_shape 模型输入尺寸(416,416) @param anchors bounding box 锚点wh:[[10,13], [16,30], [33,23], [30,61], [62,45], [59,119], [116,90], [156,198], [373,326]] @param num_classes 标签类别数,20 @return yield [image_data, *y_true], np.zeros(batch_size) => ([image_data,y1,y2,y3],loss) => ([(32,416,416,3),(32,13,13,3,25),(32,26,26,3,25),(32,52,52,3,25),(32,)]) ''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i == 0: #一轮 np.random.shuffle(annotation_lines) #打乱排序 #生成一个样本数据,image.shape=>(416,416,3),box.shape=>(20,5) #image做数据增强、归一化处理;box与image同步做变形、偏移处理,未归一化 image, box = get_random_data(annotation_lines[i], input_shape, random=True) image_data.append(image) #图像序列 box_data.append(box) #bounding box序列 i = (i + 1) % n image_data = np.array(image_data) #=>shape:(32,416,416,3) box_data = np.array(box_data) #=>shape:(32,20,5) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) #=>把样本原始数据转换为训练需要的数据格式 ''' image_data:shape=>(32,416,416,3),模型输入图像数据 y_true:[y1,y2,y3], 模型输入Box标签数据 y1:shape=>(32,13,13,3,25) y2:shape=>(32,26,26,3,25) y3:shape=>(32,52,52,3,25) np.zeros(batch_size): 模型输出loss yield [image_data, *y_true], np.zeros(batch_size) => ([image_data,y1,y2,y3],loss) => ([(32,416,416,3),(32,13,13,3,25),(32,26,26,3,25),(32,52,52,3,25),(32,)]) ''' yield [image_data, *y_true], np.zeros(batch_size)
def parser(lines): image_data = [] box_data = [] for line in lines: image, box = get_random_data(line.numpy().decode(), input_shape, random=True) image_data.append(image) box_data.append(box) image_data = np.array(image_data) box_data = np.array(box_data) y_true = [ tf.convert_to_tensor(y, tf.float32) for y in preprocess_true_boxes( box_data, input_shape, anchors, num_classes) ] image_data = tf.convert_to_tensor(image_data, tf.float32) return (image_data, *y_true)
def __getitem__(self, batch_id): image_data = [] box_data = [] for i in range(batch_id * self.batch_size, (batch_id + 1) * self.batch_size): n = len(self.info) index = int(i % n) info = self.info[index] # image, box = mc3_get_random_data(self.im_dir,info,self.input_shape) image, box = get_random_data_own(self.im_dir, info, self.input_shape) #print(box) image_data.append(image) box_data.append(box) image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, self.input_shape, self.anchors, self.num_classes) return [image_data, *y_true], np.zeros(self.batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes, random=True, verbose=False): '''data_original generator for fit_generator''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i==0 and random: np.random.shuffle(annotation_lines) image, box = get_random_data(annotation_lines[i], input_shape, random=random) image_data.append(image) box_data.append(box) i = (i+1) % n image_data = np.array(image_data) if verbose: print("Progress: ",i,"/",n) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) yield [image_data, *y_true], np.zeros(batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): '''data generator for fit_generator''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i==0: np.random.shuffle(annotation_lines)#随机打乱数据的读取顺序,有注意训练模型 image, box = get_random_data(annotation_lines[i], input_shape, random=True)#随机获取每张图片的像素集合和检测对象的box坐标信息以及每个对象的类别 image_data.append(image)#添加图片 box_data.append(box)#添加box i = (i+1) % n image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)#获取真值,用于后面计算loss #图片划分为13*13,26*26,52*52三个不同规格的cell单元格,y_true记录哪个单元格负责预测对象的box的位置信息和类别 yield [image_data, *y_true], np.zeros(batch_size) #np.zeros(batch_size)就是损失函数中那个任意给个shape符合的参数
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes, model_name=None): '''data generator for fit_generator''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] seg_data = [] for b in range(batch_size): if i == 0: np.random.shuffle(annotation_lines) image, box, seg = get_random_data(annotation_lines[i], input_shape, random=True, model_name=model_name) image_data.append(image) box_data.append(box) seg_data.append(seg) i = (i + 1) % n image_data = np.array(image_data) box_data = np.array(box_data) y_seg_data = np.array(seg_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) #np.zeros(batch_size) -> seems like the default implementation send a dummy output. if model_name in ['tiny_yolo_infusion', 'yolo_infusion']: # y_true.append(y_seg_data) # yield ({'input_1': x1, 'input_2': x2}, {'output': y}) -> https://keras.io/models/model/ yield ([image_data, *y_true], { 'yolo_loss': np.zeros(batch_size), 'seg_output': y_seg_data }) elif model_name in ['tiny_yolo_seg', 'tiny_yolo_vgg_seg']: yield ([image_data], {'seg_output': y_seg_data}) else: yield [image_data, *y_true], np.zeros(batch_size)
def _main(): annotation_path = 'train.txt' data_path = 'train.npz' output_path = 'model_data/my_yolo.h5' log_dir = 'logs/000/' classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/yolo_anchors.txt' class_names = get_classes(classes_path) anchors = get_anchors(anchors_path) input_shape = (416,416) # multiple of 32 image_data, box_data = get_training_data(annotation_path, data_path, input_shape, max_boxes=100, load_previous=True) y_true = preprocess_true_boxes(box_data, input_shape, anchors, len(class_names)) infer_model, model = create_model(input_shape, anchors, len(class_names), load_pretrained=True, freeze_body=True) train(model, image_data/255., y_true, log_dir=log_dir) infer_model.save(output_path)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): '''data generator for fit_generator''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i==0: np.random.shuffle(annotation_lines) image, box = get_random_data(annotation_lines[i], input_shape, random=True) augment = data_aug.Sequence([data_aug.HorizontalFlip(), data_aug.RandomRotate()], probs=0.5) image, tem = augment(image, box[:, :4]) box[:len(tem), :4] = tem image_data.append(image) box_data.append(box) i = (i+1) % n image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) yield [image_data, *y_true], np.zeros(batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): """ annotation_lines:标注数据的行,每行数据包含图片路径,和框的位置信息 在第0次时,将数据洗牌shuffle,调用get_random_data解析annotation_lines[i], 生成图片image和标注框box,添加至各自的列表image_data和box_data中。 """ n = len(annotation_lines) np.random.shuffle(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): # 4 i %= n image, box = get_random_data(annotation_lines[i], input_shape, random=True) image_data.append(image) box_data.append(box) i += 1 """ 索引值递增i+1,当完成n个一轮之后,重新将i置0,再次调用shuffle洗牌数据。 将image_data和box_data都转换为np数组,其中: image_data: (4, 416, 416, 3) box_data: (4, 20, 5) # 每个图片最多含有20个框 """ image_data = np.array(image_data) box_data = np.array(box_data) """ 将框的数据box_data、输入图片尺寸input_shape、anchor box列表anchors和类别数num_classes 转换为真值y_true,其中y_true是3个预测特征的列表: [(4, 13, 13, 3, 7), (4, 26, 26, 3, 7), (4, 52, 52, 3, 7)] """ y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) # 最终输出:图片数据image_data、真值y_true、每个图片的损失值np.zeros yield [image_data, *y_true], np.zeros(batch_size)
def data_generator(self, batch_data): num_classes = self.embedding.shape[0] embedding = np.tile(np.expand_dims(self.embedding, 0), (self.batch_size, 1, 1)) image_data = [] box_data = [] for data in batch_data: image, box = get_random_data(data, self.input_shape, random=True) image_data.append(image) box_data.append(box) image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, self.input_shape, self.anchors, num_classes) if self.final: anchor = np.tile(np.expand_dims(self.anchors, 0), (self.batch_size, 1, 1)) return [image_data, anchor, *y_true, embedding], np.zeros(self.batch_size) else: return [image_data, *y_true, embedding], np.zeros(self.batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): '''data generator for fit_generator''' #去生成图像资料产生器 n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i == 0: np.random.shuffle(annotation_lines) #图片乱序 image, box = get_random_data(annotation_lines[i], input_shape, random=True) #分开图片地址和标签值 image_data.append(image) box_data.append(box) i = (i + 1) % n image_data = np.array(image_data) #图片转换成矩阵 box_data = np.array(box_data) #BBOX转换成矩阵 y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) #真实坐标转化为YOLO输入坐标 yield [image_data, *y_true], np.zeros(batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): '''data generator for fit_generator''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] if (i + batch_size > n): np.random.shuffle(annotation_lines) i = 0 output = threadpool.starmap( get_random_data, zip(annotation_lines[i:i + batch_size], itertools.repeat(input_shape, batch_size))) image_data = list(zip(*output))[0] box_data = list(zip(*output))[1] i = i + batch_size image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) yield [image_data, *y_true], np.zeros(batch_size)
def __getitem__(self, idx): if idx == 0: np.random.shuffle(self.annotation_lines) image_data = [] box_data = [] start_index = idx * self.batch_size end_index = (idx + 1) * self.batch_size for index in range(start_index, end_index): image, box = get_random_data(self.annotation_lines[index], self.input_shape, random=True) image_data.append(image) box_data.append(box) image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, self.input_shape, self.anchors, self.num_classes) return [image_data, *y_true], np.zeros(self.batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): ''' data generator for fit_generator 样本生成器函数,为model.fit_generator()生成样本生成器函数 生成器函数的输出应该为:一个形如(inputs , targets) 的tuple或者一个形如(inputs, targets,sample_weight) 的tuple。 :param annotation_lines:图片路径名组成的list :param batch_size:这里是32 :param input_shape:这里是416*416 :param anchors: anchors组成的list :param num_classes: :return:返回一个tuple,yield类似于有记忆功能的return,没有加括号,返回多个值默认为tuple 返回值为:([image_data, *y_true], np.zeros(batch_size)),其中[image_data, *y_true]表示输入数据,np.zeros(batch_size)表示label数据, 因为,这里对应的model是被设置为两个输入(图像数据,真实label数据)以及一个输出(loss结果) ''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i == 0: np.random.shuffle(annotation_lines) # 读取指点图片的图像数据和box数据,这个label数据是已经resized到input_shape(416,416)大小的 image, box = get_random_data(annotation_lines[i], input_shape, random=True) image_data.append(image) box_data.append(box) i = (i + 1) % n # i在0-n之间循环,表示当前采集的样本序号 image_data = np.array( image_data ) # box_data和image_data每次加入batch_size个样本,然后生成网络需要的label y_true后清空 box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) yield [image_data, *y_true], np.zeros(batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes, random=True, verbose=False): """ Data generator function for fit_generator :param annotation_lines: :param batch_size: :param input_shape: :param anchors: :param num_classes: :param random: :param verbose: :return: """ n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i == 0: np.random.shuffle(annotation_lines) image, box = get_random_data(annotation_lines[i], input_shape, random=random) image_data.append(image) box_data.append(box) i = (i + 1) % n image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) yield [image_data, *y_true], np.zeros(batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i == 0: # 随机排列图片顺序 np.random.shuffle(annotation_lines) # image_data: (16, 416, 416, 3) # box_data: (16, 20, 5) # 每个图片最多含有20个框 image, box = get_random_data(annotation_lines[i], input_shape, random=True) image_data.append(image) box_data.append(box) i = (i + 1) % n image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) yield [image_data, *y_true], np.zeros(batch_size)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes): '''data generator for fit_generator 总的来说就是生成一个batch_size的数据 ''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] for b in range(batch_size): if i==0: np.random.shuffle(annotation_lines) # 随机处理输入数据,包括图片和bbox image, box = get_random_data(annotation_lines[i], input_shape, random=True) image_data.append(image) box_data.append(box) i = (i+1) % n image_data = np.array(image_data) box_data = np.array(box_data) # 这里还需要转换bbox的格式 # 因为YOLO3里面3个feature map,需要对应地转换,将绝对坐标(原图像)转换为相对坐标 y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) # 能够得到一个batch_size的训练数据,注意"*"号的使用 yield [image_data, *y_true], np.zeros(batch_size)
def main(argv=None): np.random.seed(0) safe_mkdir("output/abuse") input_h = 1013 input_w = 1919 inputs = tf.placeholder(tf.float32, [None, None, None, 3]) np.random.seed(0) img = np.asarray(Image.open('../data/page_based/tj.png')).astype( np.float32) inv_ratio_h = 416.0 / input_h inv_ratio_w = 416.0 / input_w target_box = np.asarray([[[ target_pos[0][0] * inv_ratio_w, target_pos[0][1] * inv_ratio_h, target_pos[1][0] * inv_ratio_w, target_pos[1][1] * inv_ratio_h, 0 ]]]) true_boxes = preprocess_true_boxes(target_box, [416, 416], anchors, 1) eps = 4.0 epochs = 500 mask_h = src_pos[1][1] - src_pos[0][1] mask_w = src_pos[1][0] - src_pos[0][0] mask_val = img[src_pos[0][1]:src_pos[1][1], src_pos[0][0]:src_pos[1][0]] mask = tf.Variable(initial_value=mask_val, dtype=tf.float32) padded_mask = tf.image.pad_to_bounding_box(mask, src_pos[0][1], src_pos[0][0], tf.shape(inputs)[1], tf.shape(inputs)[2]) black_box = tf.ones([mask_h, mask_w, 3], dtype=tf.float32) black_mask = 1.0 - tf.image.pad_to_bounding_box(black_box, src_pos[0][1], src_pos[0][0], tf.shape(inputs)[1], tf.shape(inputs)[2]), blacked_inputs = tf.multiply(inputs, black_mask) masked_input = tf.clip_by_value(tf.add(blacked_inputs, padded_mask), 0, 255) inputs_resized = tf.image.resize_images(masked_input, (416, 416), align_corners=True) config = tf.ConfigProto() config.gpu_options.per_process_gpu_memory_fraction = 0.25 sess = tf.Session(config=config) K.set_session(sess) sess.run(tf.global_variables_initializer()) model = load_model('../models/page_based_yolov3.h5') model.layers.pop(0) newInput = Input(tensor=inputs_resized / 255.) newOut = model(newInput) model = Model(newInput, newOut) y_true = [tf.placeholder(shape=(1, 416//{0:32, 1:16, 2:8}[l], 416//{0:32, 1:16, 2:8}[l], \ len(anchors)//3, 1+5), dtype=tf.float32) for l in range(3)] print([y.get_shape().as_list() for y in y_true]) loss = yolo_loss([*model.output, *y_true], anchors, 1) grad = tf.gradients(loss, mask)[0] opt = tf.train.AdamOptimizer(10.0) grad_ph = tf.placeholder(shape=grad.get_shape().as_list(), dtype=tf.float32) assign_op = opt.apply_gradients([(grad_ph, mask)]) sess.run(tf.variables_initializer(opt.variables())) assign_eps_op = tf.assign( mask, tf.clip_by_value(mask, mask_val - eps, mask_val + eps)) input_image_shape = K.placeholder(shape=(2, )) boxes, scores, classes = yolo_eval(model.output, anchors, 1, input_image_shape, score_threshold=0.5, iou_threshold=0.4) time_since_success = np.inf for i in range(epochs): curr_grad, curr_loss, curr_img, out_boxes, out_scores, out_classes = sess.run( [grad, loss, masked_input, boxes, scores, classes], feed_dict={ inputs: np.expand_dims(img, 0).astype(np.float32), input_image_shape: [416, 416], y_true[0]: np.asarray(true_boxes[0]), y_true[1]: np.asarray(true_boxes[1]), y_true[2]: np.asarray(true_boxes[2]), K.learning_phase(): 0 }) num_detect = len(out_boxes) print('test loss={:.3f}'.format(curr_loss), 'num_boxes={}'.format(num_detect)) sess.run(assign_op, feed_dict={ grad_ph: curr_grad / (np.linalg.norm(curr_grad.reshape(-1)) + 1e-8) }) sess.run(assign_eps_op) if ((i % 50 == 0) or (time_since_success > 50)) and num_detect > 0: img1 = draw_boxes(curr_img[0].astype(np.uint8), out_boxes, out_scores, out_classes) img1.save("output/abuse/tj_{}.png".format(i)) plt.imshow(img1) plt.show() time_since_success = 0 else: time_since_success += 1
yolo_model = yolo_body(Input(shape=(None, None, 3)), num_anchors // 3, num_classes) yolo_model.load_weights(model_path) annotation_path = 'train_nuro.txt' val_split = 0.99 with open(annotation_path) as f: annotation_lines = f.readlines() num_val = int(len(annotation_lines) * val_split) num_train = len(annotation_lines) - num_val input_shape = (416, 416) n = len(annotation_lines) image, box = get_random_data(annotation_lines[0], input_shape, random=False) image_data = [] box_data = [] image_data.append(image) box_data.append(box) image_data = np.array(image_data) box_data = np.array(box_data) batch_data = [] batch_data.append(annotation_lines[0]) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes, batch_data) # model = create_model(input_shape, anchors, num_classes, freeze_body=2, weights_path=model_path, grid_loss=False)
def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes, model_name=None, num_yolo_heads=None): '''data generator for fit_generator''' n = len(annotation_lines) i = 0 while True: image_data = [] box_data = [] seg_data = [] for b in range(batch_size): if i == 0: np.random.shuffle(annotation_lines) image, box, seg = get_random_data( annotation_lines[i], input_shape, random=train_config['data_augmentation'], model_name=model_name) image_data.append(image) box_data.append(box) seg_data.append(seg) i = (i + 1) % n image_data = np.array(image_data) box_data = np.array(box_data) y_seg_data = np.array(seg_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes, model_name=model_name, num_yolo_heads=num_yolo_heads) if model_name in ['tiny_yolo_infusion', 'yolo_infusion']: #old style # yield [image_data, *y_true, y_seg_data], np.zeros(batch_size) #new style # yield ({'input_1': x1, 'input_2': x2}, {'output': y}) -> https://keras.io/models/model/ yield ([image_data, *y_true], { 'yolo_loss': np.zeros(batch_size), 'seg_output': y_seg_data }) elif model_name in ['tiny_yolo_infusion_hydra']: #old style # y_seg_reorg = list(zip(*y_seg_data)) # y_seg_data_1 = np.array(y_seg_reorg[0]) ## print('y_seg_data_1',y_seg_data_1.shape) # y_seg_data_2 = np.array(y_seg_reorg[1]) ## print('y_seg_data_2',y_seg_data_2.shape) # yield [image_data, *y_true, y_seg_data_1, y_seg_data_2 ], np.zeros(batch_size) #new style: not implemented yet. pass elif model_name in [ 'tiny_yolo', 'yolo', 'yolo_small_objs', 'tiny_yolo_small_objs' ]: yield [image_data, *y_true], np.zeros( batch_size ) #np.zeros(batch_size) -> seems like the default implementation send a dummy output. else: raise Exception('unknown model.')