转自:https://blog.csdn.net/KKKSQJ/article/details/83587138

original

Based on keras-yolov3, understanding of the principle and code details

October 31, 2018 17:37:43
Aries seven seven seven
reading number: 2917

This article GitHub  source code : https://github.com/qqwweee/keras-yolo3

Yolov3 paper address: https://pjreddie.com/media/files/papers/YOLOv3.pdf

Yolov3 official website: https://pjreddie.com/darknet/yolo/

Recently I was very interested in YOLOV3 and read a lot of information. Made some related projects. So I wrote down some experiences to review the query later.

YOLO, the abbreviation of You Only Look Once, is an object detection algorithm based on Convolutional Neural Network (CNN).

Yolo design concept

The yolo algorithm as a whole uses CNN to detect end-to-end targets. The process is shown in Figure 1.

Figure 1

Specifically (based on YOLOV3)

1: Enter an image of any size to keep the aspect ratio unchanged, zoom to w or h to 416, and then overwrite the new image on 416*416 as the input to the network. That is, the input of the network is a 416*416, 3-channel RGB picture.

2: Run the network. YOLO's CNN network divides the picture into  S*S  grids (yolov3 multi-scale prediction, output 3 layers, each layer S * S grids, respectively 13*13, 26 * 26, 52 * 52), then each The cell is responsible for detecting the targets whose center points fall within the grid, as shown in Figure 2. Each cell needs to predict  3*(4+1+B) values. If the input picture is divided into  S*S  grids, then the final predicted value of each layer is  the tensor of  S*S*3*(4+1+B) size. B: number of categories (coco set is 80), that is, B=80. 3 is the number of anchorboxes per layer, and 4 is the bounding box size and position (x, y, w, h)1 is the confidence level.

3: Through NMS, non-maximum value suppression, filter out box boxes , output box class_boxes and confidence class_box_scores, then generate category information classes, generate final detection data frame, and return

      

Figure 2 Figure 3

 YOLOV3 network structure:

Multiscale:

Yolov3 uses multi-scale prediction. [(13*13)(26*26)(52*52)]

• Small scale: (13*13 feature map)

  • The network receives a picture of (416 * 416), downsampling (416 / 2 ˆ 5 = 13) and output (13 * 13) after 5 convolutions of 2 steps.

• Mesoscale: (26*26 feature map)

  • The convolutional layer of the penultimate layer in the small scale is upsampled (x2, up sampling) and added to the last 13x13 size feature map, and output (26*26).

• Large scale: (52*52 feature map)

  • Operation with mesoscale output (52*52)

Benefit: Let the network learn deep and shallow features at the same time, by superimposing the adjacent features of the shallow feature map to different channels (not spatial locations), similar to identity mapping in Resnet. This method superimposes the feature map of 26x26x512 into the feature map of 13x13x2048, and connects with the original deep feature map, which makes the model have fine-grained features and increases the ability to recognize small targets.

Anchor box:

There are a total of 9 yolov3 anchor boxes, which are obtained by k-means clustering. On the COCO dataset, the nine clusters are: (10*13); (16*30); (33*23); (30*61); (62*45); (59*119); *90); (156*198); (373*326).

Different size feature maps correspond to different sizes of a priori frames.

  • 13*13feature map corresponds to [(116*90), (156*198), (373*326)]
  • 26*26feature map corresponds to [(30*61), (62*45), (59*119)]
  • 52*52feature map corresponds to [(10*13), (16*30), (33*23)]

Reason: The larger the feature map, the smaller the feeling field. The more sensitive it is to small targets, so choose a small anchor box.

The smaller the feature map, the larger the feeling field. The more sensitive the big target is, so choose the big anchor box.

Border prediction:

Prediction tx ty tw th

  • Perform sigmoid on tx and ty, and add the corresponding offset (Cx, Cy below)
  • Exp on th and tw and multiply by the corresponding anchor value
  • Multiply tx, ty, th, tw by the corresponding stride, ie: 416/13, 416 ⁄ 26, 416 ⁄ 52
  • Finally, using sigmoid to sigmoid the Objectness and Classes confidence to get a probability of 0~1, the reason is to replace the previous version of softmax with sigmoid, because softmax will expand the maximum category probability value and suppress other category probability values.

(tx, ty): The offset of the target center point relative to the top left corner of the grid at which the point is located, normalized by sigmoid. The value belongs to [0, 1]. As shown in the figure (0.3, 0.4)

(cx, cy): The number of grids in the upper left corner of the grid where the point is different from the top left corner. As shown in Figure (1, 1)

(pw, ph): the side length of the anchor box

(tw,th): predict the width and height of the border

PS: The final frame coordinates are bx, by, bw, bh. The network learning goal is tx, ty, tw, th

Loss function LOSS

  • YOLO V3 turns Softmax loss in YOLOV2 into Logistic loss

This picture is for reference only and is slightly different from YOLOV3

    

Code interpretation: source code detection part

Usage

  • Git Clone https://github.com/qqwweee/keras-yolo3
  • Download yolov3 weights from the YOLO  website
  • Convert the darknet version of the yolo model to Keras model
  • Run YOLO dection

  1. YOLO类的初始化参数:
  2. class YOLO(object):

  1. _defaults = {
  2. "model_path": 'model_data/yolo.h5', #训练好的模型
  3. "anchors_path": 'model_data/yolo_anchors.txt', # anchor box 9个, 从小到大排列
  4. "classes_path": 'model_data/coco_classes.txt', #类别数
  5. "score" : 0.3, #score 阈值
  6. "iou" : 0.45, #iou 阈值
  7. "model_image_size" : (416, 416), #输入图像尺寸
  8. "gpu_num" : 1, #gpu数量
  9. }

  1. run yolo_video.py
  2. def detect_img(yolo):
  3. while True:
  4. img = input('Input image filename:') #输入一张图片
  5. try:
  6. image = Image.open(img)
  7. except:
  8. print('Open Error! Try again!')
  9. continue
  10. else:
  11. r_image = yolo.detect_image(image) #进入yolo.detect_image 进行检测
  12. r_image.show()
  13. yolo.close_session()
  14. detect_image()函数在yolo.py第102行
  15. def detect_image(self, image):
  16. start = timer()
  17. if self.model_image_size != (None, None): #判断图片是否存在
  18. assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
  19. assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
  20. #assert断言语句的语法格式 model_image_size[0][1]指图像的w和h,且必须是32的整数倍
  21. boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size))) #letterbox_image()定义在utils.py的第20行。输入参数(图像 ,(w=416,h=416)),输出一张使用填充来调整图像的纵横比不变的新图。
  22. else:
  23. new_image_size = (image.width - (image.width % 32),
  24. image.height - (image.height % 32))
  25. boxed_image = letterbox_image(image, new_image_size)
  26. image_data = np.array(boxed_image, dtype='float32')
  27. print(image_data.shape) #(416,416,3)
  28. image_data /= 255. #归一化
  29. image_data = np.expand_dims(image_data, 0)
  30.   #批量添加一维 -> (1,416,416,3) 为了符合网络的输入格式 -> (bitch, w, h, c)
  31. out_boxes, out_scores, out_classes = self.sess.run(
  32. [self.boxes, self.scores, self.classes],
  33.   #目的为了求boxes,scores,classes,具体计算方式定义在generate()函数内。在yolo.py第61行
  34. feed_dict={ #喂参数
  35. self.yolo_model.input: image_data, #图像数据
  36. self.input_image_shape: [image.size[1], image.size[0]], #图像尺寸
  37. K.learning_phase(): 0 #学习模式 0:测试模型。 1:训练模式
  38. })
  39. print('Found {} boxes for {}'.format(len(out_boxes), 'img'))
  40. # 绘制边框,自动设置边框宽度,绘制边框和类别文字,使用Pillow绘图库

  1.    font = ImageFont.truetype(font='font/FiraMono-Medium.otf',
  2.     size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32')) #字体
  3.      thickness = (image.size[0] + image.size[1]) // 300 #厚度
  4.      for i, c in reversed(list(enumerate(out_classes))):
  5.      predicted_class = self.class_names[c] #类别
  6.      box = out_boxes[i] #框
  7.      score = out_scores[i] #置信度
  8.   label = '{} {:.2f}'.format(predicted_class, score) #标签
  9.   draw = ImageDraw.Draw(image) #画图
  10.   label_size = draw.textsize(label, font)  # 标签文字
  11.   top, left, bottom, right = box
  12.   top = max(0, np.floor(top + 0.5).astype('int32'))
  13.   left = max(0, np.floor(left + 0.5).astype('int32'))
  14.   bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
  15.   right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
  16.   print(label, (left, top), (right, bottom)) #边框
  17.   if top - label_size[1] >= 0: #标签文字
  18.   text_origin = np.array([left, top - label_size[1]])
  19.   else:
  20.   text_origin = np.array([left, top + 1])
  21.   # My kingdom for a good redistributable image drawing library.
  22.   for i in range(thickness): #画框
  23.   draw.rectangle(
  24.   [left + i, top + i, right - i, bottom - i],
  25.   outline=self.colors[c])
  26.   draw.rectangle( #文字背景
  27.   [tuple(text_origin), tuple(text_origin + label_size)],
  28.   fill=self.colors[c])
  29.   draw.text(text_origin, label, fill=(0, 0, 0), font=font) #文案
  30.   del draw
  31.   end = timer()
  32.   print(end - start)
  33.   return image
generate()在yolo.py第61行

  1. def generate(self):
  2. model_path = os.path.expanduser(self.model_path) #获取model路径
  3. assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.' #判断model是否以h5结尾
  4. # Load model, or construct model and load weights.
  5. num_anchors = len(self.anchors) #num_anchors = 9。yolov3有9个先验框
  6. num_classes = len(self.class_names) #num_cliasses = 80。 #coco集一共80类
  7. is_tiny_version = num_anchors==6 # default setting is_tiny_version = False
  8. try:
  9. self.yolo_model = load_model(model_path, compile=False) #下载model
  10. except:
  11. self.yolo_model = tiny_yolo_body(Input(shape=(None,None,3)), num_anchors//2, num_classes) \
  12. if is_tiny_version else yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)
  13. self.yolo_model.load_weights(self.model_path) # 确保model和anchor classes 对应
  14. else:
  15. assert self.yolo_model.layers[-1].output_shape[-1] == \
  16.   # model.layer[-1]:网络最后一层输出。 output_shape[-1]:输出维度的最后一维。 -> (?,13,13,255)
  17. num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
  18.   #255 = 9/3*(80+5). 9/3:每层特征图对应3个anchor box 80:80个类别 5:4+1,框的4个值+1个置信度
  19. 'Mismatch between model and given anchor and class sizes'
  20. print('{} model, anchors, and classes loaded.'.format(model_path))

  1. # 生成绘制边框的颜色。
  2. hsv_tuples = [(x / len(self.class_names), 1., 1.)
  3.   #h(色调):x/len(self.class_names) s(饱和度):1.0 v(明亮):1.0
  4. for x in range(len(self.class_names))]
  5. self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) #hsv转换为rgb
  6. self.colors = list(
  7. map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
  8. self.colors))
  9. #hsv取值范围在【0,1】,而RBG取值范围在【0,255】,所以乘上255
  10. np.random.seed(10101) # np.random.seed():产生随机种子。固定种子为一致的颜色
  11. np.random.shuffle(self.colors) # 调整颜色来装饰相邻的类。
  12. np.random.seed(None) #重置种子为默认

# Generate output tensor targets for filtered bounding boxes.

self.input_image_shape = K.placeholder(shape=(2, ))      #K.placeholder: placeholder in keras

if self.gpu_num>=2:

    self.yolo_model = multi_gpu_model( Self.yolo_model, gpus=self.gpu_num)

boxes, scores, classes = yolo_eval (self.yolo_model.output, self.anchors,

        len(self.class_names), self.input_image_shape,

        score_threshold=self.score, iou_threshold=self.iou )    #yolo_eval (): evaluation function Yolo

return boxes, scores, classes


  1. def yolo_eval(yolo_outputs, #模型输出,格式如下【(?,13,13,255)(?,26,26,255)(?,52,52,255)】 ?:bitch size; 13-26-52:多尺度预测; 255:预测值(3*(80+5))
  2. anchors, #[(10,13), (16,30), (33,23), (30,61), (62,45), (59,119), (116,90), (156,198),(373,326)]
  3. num_classes,     # 类别个数,coco集80类
  4. image_shape, #placeholder类型的TF参数,默认(416, 416);
  5. max_boxes=20, #每张图每类最多检测到20个框同类别框的IoU阈值,大于阈值的重叠框被删除,重叠物体较多,则调高阈值,重叠物体较少,则调低阈值
  6. score_threshold=.6, #框置信度阈值,小于阈值的框被删除,需要的框较多,则调低阈值,需要的框较少,则调高阈值;
  7. iou_threshold=.5): #同类别框的IoU阈值,大于阈值的重叠框被删除,重叠物体较多,则调高阈值,重叠物体较少,则调低阈值
  8. """Evaluate YOLO model on given input and return filtered boxes."""
  9. num_layers = len(yolo_outputs) #yolo的输出层数;num_layers = 3 -> 13-26-52
  10. anchor_mask = [[6,7,8], [3,4,5], [0,1,2]] if num_layers==3 else [[3,4,5], [1,2,3]]
  11.   # default setting #每层分配3个anchor box.如13*13分配到【6,7,8】即【(116,90)(156,198)(373,326)】
  12. input_shape = K.shape(yolo_outputs[0])[1:3] * 32
  13.   #输入shape(?,13,13,255);即第一维和第二维分别*32 ->13*32=416; input_shape:(416,416)
  14. boxes = []
  15. box_scores = []
  16. for l in range(num_layers):
  17. _boxes, _box_scores = yolo_boxes_and_scores(yolo_outputs[l],
  18. anchors[anchor_mask[l]], num_classes, input_shape, image_shape)
  19. boxes.append(_boxes)
  20. box_scores.append(_box_scores)
  21. boxes = K.concatenate(boxes, axis=0) #K.concatenate:将数据展平 ->(?,4)
  22. box_scores = K.concatenate(box_scores, axis=0) # ->(?,)
  23. mask = box_scores >= score_threshold #MASK掩码,过滤小于score阈值的值,只保留大于阈值的值
  24. max_boxes_tensor = K.constant(max_boxes, dtype='int32') #最大检测框数20
  25. boxes_ = []
  26. scores_ = []
  27. classes_ = []
  28. for c in range(num_classes):
  29. # TODO: use keras backend instead of tf.
  30. class_boxes = tf.boolean_mask(boxes, mask[:, c]) #通过掩码MASK和类别C筛选框boxes
  31. class_box_scores = tf.boolean_mask(box_scores[:, c], mask[:, c]) #通过掩码MASK和类别C筛选scores
  32. nms_index = tf.image.non_max_suppression( #运行非极大抑制
  33. class_boxes, class_box_scores, max_boxes_tensor, iou_threshold=iou_threshold)
  34. class_boxes = K.gather(class_boxes, nms_index) #K.gather:根据索引nms_index选择class_boxes
  35. class_box_scores = K.gather(class_box_scores, nms_index) #根据索引nms_index选择class_box_score)
  36. classes = K.ones_like(class_box_scores, 'int32') * c #计算类的框得分
  37. boxes_.append(class_boxes)
  38. scores_.append(class_box_scores)
  39. classes_.append(classes)
  40. boxes_ = K.concatenate(boxes_, axis=0)
  41.   #K.concatenate().将相同维度的数据连接在一起;把boxes_展平。 -> 变成格式:(?,4); ?:框的个数;4:(x,y,w,h)
  42. scores_ = K.concatenate(scores_, axis=0) #变成格式(?,)
  43. classes_ = K.concatenate(classes_, axis=0) #变成格式(?,)
  44. return boxes_, scores_, classes_
  45. yolo_boxes_and_scores()在model.py的第176行

  1. def yolo_boxes_and_scores(feats, anchors, num_classes, input_shape, image_shape):
  2. # feats:输出的shape,->(?,13,13,255); anchors:每层对应的3个anchor box
  3. # num_classes: 类别数(80); input_shape:(416,416); image_shape:图像尺寸
  4. '''Process Conv layer output'''
  5. box_xy, box_wh, box_confidence, box_class_probs = yolo_head(feats,
  6. anchors, num_classes, input_shape)
  7. #yolo_head():box_xy是box的中心坐标,(0~1)相对位置;box_wh是box的宽高,(0~1)相对值;
  8. #box_confidence是框中物体置信度;box_class_probs是类别置信度;
  9. boxes = yolo_correct_boxes(box_xy, box_wh, input_shape, image_shape)
  10.   #将box_xy和box_wh的(0~1)相对值,转换为真实坐标,输出boxes是(y_min,x_min,y_max,x_max)的值
  11. boxes = K.reshape(boxes, [-1, 4])
  12.   #reshape,将不同网格的值转换为框的列表。即(?,13,13,3,4)->(?,4) ?:框的数目
  13. box_scores = box_confidence * box_class_probs
  14.   #框的得分=框的置信度*类别置信度
  15. box_scores = K.reshape(box_scores, [-1, num_classes])
  16. #reshape,将框的得分展平,变为(?,80); ?:框的数目
  17. return boxes, box_scores
  18. yolo_head()在model.py的第122行

  1. def yolo_head(feats, anchors, num_classes, input_shape, calc_loss=False): #参数同上
  2. """Convert final layer features to bounding box parameters."""
  3. num_anchors = len(anchors) #num_anchors = 3
  4. # Reshape to batch, height, width, num_anchors, box_params.
  5. anchors_tensor = K.reshape(K.constant(anchors), [1, 1, 1, num_anchors, 2]) #reshape ->(1,1,1,3,2)
  6. grid_shape = K.shape(feats)[1:3] # height, width (?,13,13,255) -> (13,13)
  7. #grid_y和grid_x用于生成网格grid,通过arange、reshape、tile的组合, 创建y轴的0~12的组合grid_y,再创建x轴的0~12的组合grid_x,将两者拼接concatenate,就是grid;
  8. grid_y = K.tile(K.reshape(K.arange(0, stop=grid_shape[0]), [-1, 1, 1, 1]),
  9. [1, grid_shape[1], 1, 1])
  10. grid_x = K.tile(K.reshape(K.arange(0, stop=grid_shape[1]), [1, -1, 1, 1]),
  11. [grid_shape[0], 1, 1, 1])
  12. grid = K.concatenate([grid_x, grid_y])
  13. grid = K.cast(grid, K.dtype(feats)) #K.cast():把grid中值的类型变为和feats中值的类型一样
  14. feats = K.reshape(
  15. feats, [-1, grid_shape[0], grid_shape[1], num_anchors, num_classes + 5])
  16. #将feats的最后一维展开,将anchors与其他数据(类别数+4个框值+框置信度)分离
  17. # Adjust preditions to each spatial grid point and anchor size.
  18. #xywh的计算公式,tx、ty、tw和th是feats值,而bx、by、bw和bh是输出值,如下图
  19. box_xy = (K.sigmoid(feats[..., :2]) + grid) / K.cast(grid_shape[::-1], K.dtype(feats))
  20. box_wh = K.exp(feats[..., 2:4]) * anchors_tensor / K.cast(input_shape[::-1], K.dtype(feats))
  21. box_confidence = K.sigmoid(feats[..., 4:5])
  22. box_class_probs = K.sigmoid(feats[..., 5:])
  23. #sigmoid:σ
  24.   # ...操作符,在Python中,“...”(ellipsis)操作符,表示其他维度不变,只操作最前或最后1维;


  1. if calc_loss == True:
  2. return grid, feats, box_xy, box_wh
  3. return box_xy, box_wh, box_confidence, box_class_probs
  4. yolo_correct_boxes()在model.py的第150行

  1. def yolo_correct_boxes(box_xy, box_wh, input_shape, image_shape): #得到正确的x,y,w,h
  2. '''Get corrected boxes'''
  3. box_yx = box_xy[..., ::-1] #“::-1”是颠倒数组的值
  4. box_hw = box_wh[..., ::-1]
  5. input_shape = K.cast(input_shape, K.dtype(box_yx))
  6. image_shape = K.cast(image_shape, K.dtype(box_yx))
  7. new_shape = K.round(image_shape * K.min(input_shape/image_shape))
  8. offset = (input_shape-new_shape)/2./input_shape
  9. scale = input_shape/new_shape
  10. box_yx = (box_yx - offset) * scale
  11. box_hw *= scale
  12. box_mins = box_yx - (box_hw / 2.)
  13. box_maxes = box_yx + (box_hw / 2.)
  14. boxes = K.concatenate([
  15. box_mins[..., 0:1], #y_min
  16. box_mins[..., 1:2], #x_min
  17. box_maxes[..., 0:1], #y_max
  18. box_maxes[..., 1:2] #x_max
  19. ])
  20. # Scale boxes back to original image shape.
  21. boxes *= K.concatenate([image_shape, image_shape])
  22. return boxes

 OK, that's all! Enjoy it!

reference:

Https://blog.csdn.net/qq_14845119/article/details/80335225

https://www.cnblogs.com/makefile/p/YOLOv3.html

Https://www.colabug.com/4125223.html

 

Yolov_3 网络结构分析的更多相关文章

  1. macvlan 网络结构分析 - 每天5分钟玩转 Docker 容器技术(56)

    上一节我们创建了 macvlan 并部署了容器,本节详细分析 macvlan 底层网络结构. macvlan 网络结构分析 macvlan 不依赖 Linux bridge,brctl show 可以 ...

  2. 第 8 章 容器网络 - 064 - Weave 网络结构分析

    Weave 网络结构分析 在 host1 中运行容器 bbox1: eval $(weave env) docker run --name bbox1 -itd busybox 首先执行 eval $ ...

  3. 第 8 章 容器网络 - 056 - macvlan 网络结构分析

    macvlan 网络结构分析 macvlan 不依赖 Linux bridge,brctl show 可以确认没有创建新的 bridge. 查看一下容器 bbox1 的网络设备: 除了 lo,容器只有 ...

  4. Weave 网络结构分析 - 每天5分钟玩转 Docker 容器技术(64)

    上一节我们安装并创建了 Weave 网络,本节将部署容器并分析网络结构.在 host1 中运行容器 bbox1: eval $(weave env) docker run --name bbox1 - ...

  5. 064、Weave网络结构分析(2019-04-04 周四)

    参考https://www.cnblogs.com/CloudMan6/p/7482035.html   Weave网络使用之前需要执行  eval $(weave env) ,其作用是将后续的doc ...

  6. 056、macvlan网络结构分析(2019-03-25 周一)

    参考https://www.cnblogs.com/CloudMan6/p/7383919.html   macvlan不依赖linux bridge   brctl show 可以确认没有创建新的b ...

  7. 62-Weave 网络结构分析

    上一节我们安装并创建了 Weave 网络,本节将部署容器并分析网络结构. 在 host1 中运行容器 bbox1: eval $(weave env) docker run --name bbox1 ...

  8. centos7下安装docker(15.3跨主机网络-macvlan)

    除了ovrlay,docker还开发了另一个支持跨主机容器的driver:macvlan macvlan本身是linu kernel模块,其功能是允许在同一物理网卡上配置多了MAC地址,即:多个int ...

  9. 【转】VLAN原理详解

    1.为什么需要VLAN 1.1 什么是VLAN? VLAN(Virtual LAN),翻译成中文是“虚拟局域网”.LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成的企业网络.V ...

随机推荐

  1. matlab前景分割

    用最简单的差分法实现了一下前景分割.使用的mall数据集. 思路是这样的:首先设定一个队列的长度,若读取的图片张数少于队列长度则以当前读取到的图片做平均.否则则以队列中的图片做平均. 这样之后和当前图 ...

  2. scrapy 爬虫踩过的坑(I)

    问题1:正则表达式没问题,但是爬虫进不了item方法 分析: 1. 可能是下载不到list 页面的内容.可以用 scrapy shell url 进行测试 2. 可能是allowed_domains ...

  3. 四. Jmeter--JDBC 请求

    一,  SQLserver 1.下载 JDBC Driver (sqljdbc_6.0.8112.100_enu.exe) https://www.microsoft.com/en-us/downlo ...

  4. weblogic 配置了ssl

    jingyan.baidu.com/article/72ee561abfe531e16138dfb5.html http://blog.sina.com.cn/s/blog_7ffec3e201019 ...

  5. Linux CGI编程基础【整理】

    Linux CGI编程基础 1.为什么使用CGI? 如前面所见,任何的HTML均是静态网页,它无法实现一些复杂的功能,而CGI可以为我们实现.如:a.列出服务器上某个目录中的文件,对目录中的文件进行操 ...

  6. linux动态库编译和使用详细剖析 - 后续

    引言 - 也许是修行 很久以前写过关于动态库科普文章, 废话反正是说了好多. 核心就是在 linux 上面玩了一下 dlopen : ) linux动态库编译和使用详细剖析 - https://www ...

  7. 10.python3标准库--加密

    ''' 加密可以保护消息安全,以便验证其正确性并保护消息不被截获. python的加密支持包括hashlib和hmac,hashlib使用标准算法生成消息内容签名,hmac则用于验证消息在传输过程中未 ...

  8. C/C++——C语言数组名与指针

    版权声明:原创文章,转载请注明出处. 1. 一维数组名与指针 对于一维数组来说,数组名就是指向该数组首地址的指针,对于: ]; array就是该数组的首地址,如果我们想定义一个指向该数组的指针,我们可 ...

  9. caffe多个gpu数据合并到一起

    当多GPU树形拓扑构建完毕,数据预缓冲到GPU显存,开始进入多GPU并行训练.Caffe的Solver提供了两个用于多GPU训练的回调函数:on_start()和on_gradient_ready() ...

  10. 让Linux应用更加得心应手的

    1.计算文件数和目录数  下面的语句可以帮你计算有多少个文件和多少个目录 # ls -l * |grep "^-"|wc -l ---- to count files # ls - ...