We value your privacy. When you visit our website, please consent to the use of all cookies. For more information on personal data processing, please visit  《Privacy and Protection Policy》.

Application of optical computing in RetinaNet object detection task

2026.04.02

1. Dataset Introduction

The full name of the DOTA dataset is: Dataset for Object Determination in Aerial Images.

The DOTA dataset v1.0 contains 2806 images of 4000 × 4000 pixels, containing a total of 188282 objects.

DOTA Dataset Paper Introduction: https://arxiv.org/pdf/1711.10398.pdf

Dataset Website:

1.png

The DOTA dataset has three versions:


* DOTAV1.0

Number of categories: 15

Category names: plane, ship, storage tank, baseball diamond, tennis court, basketball court, ground track field, harbor, bridge, large vehicle, small vehicle, helicopter, roundabout, soccer ball field, swimming pool

* DOTAV1.5

Number of categories: 16

Category names: plane, ship, storage tank, baseball diamond, tennis court, basketball court, ground track field, harbor, bridge, large vehicle, small vehicle, helicopter, roundabout, soccer ball field, swimming pool, container crane

* DOTAV2.0

Number of categories: 18

Category names: plane, ship, storage tank, baseball diamond, tennis court, basketball court, ground track field, harbor, bridge, large vehicle, small vehicle, helicopter, roundabout, soccer ball field, swimming pool, container crane, airport, helipad

(1) Labels

When augmenting a dataset, we need to know the relevant label file format.

Each object has 10 values. The first 8 represent the coordinates of the four corners of a rectangle, the 9th represents the object category, and the 10th represents the difficulty level of recognition, with 0 indicating easy and 1 indicating difficult.

Below is a similar file.

950.0 851.0 931.0 852.0 932.0 817.0 952.0 817.0 small-vehicle 1

475.0 982.0 456.0 982.0 461.0 841.0 481.0 842.0 large-vehicle 0

424.0 978.0 400.0 982.0 403.0 840.0 426.0 839.0 large-vehicle 0

395.0 984.0 373.0 985.0 376.0 842.0 399.0 843.0 large-vehicle 0

365.0 979.0 344.0 978.0 346.0 839.0 369.0 838.0 large-vehicle 0

337.0 977.0 317.0 977.0 321.0 836.0 339.0 835.0 large-vehicle 0

310.0 978.0 287.0 979.0 286.0 838.0 311.0 838.0 large-vehicle 0

154.0 947.0 250.0 947.0 250.0 971.0 154.0 971.0 large-vehicle 0

140.0 894.0 255.0 894.0 255.0 919.0 140.0 919.0 large-vehicle 0

116.0 862.0 236.0 862.0 236.0 888.0 116.0 888.0 large-vehicle 0

146.0 771.0 269.0 771.0 269.0 796.0 146.0 796.0 large-vehicle 0

136.0 741.0 271.0 741.0 271.0 766.0 136.0 766.0 large-vehicle 0

136.0 713.0 271.0 713.0 271.0 735.0 136.0 735.0 large-vehicle 0

 

It can be seen that its label is a rotating box composed of four points. Note: Since the visualization code requires the coordinate point input to be an integer, the coordinate point of the output object is rounded down, which will result in some loss of precision.


(2) Data Augmentation


Related data augmentation, DOTA (obb) data augmentation (methods include: changing brightness, adding noise, rotating angle, mirroring, translating, cropping, cutout), related code is as follows:


2025.8.3: Data Augmentation (dota 4-point conversion)


# -*- coding=utf-8 -*-


# Includes:


# 6. Cropping (requires changing the bbox)


# 5. Translation (requires changing the bbox)


# 1. Changing brightness


# 2. Adding noise


# 3. Rotating angle (requires changing the bbox)


# 4. Mirroring (requires changing the bbox)


# 7. Cutout


# Note:


# random.seed(), the same seed will generate the same random number!!

import time

import random

import cv2 as cv

import os

import math

import numpy as np

from skimage.util import random_noise

from skimage import exposure

import shutil

import imutils

  

# adujust brightness

def changeLight(img,inputtxt,outputiamge,outputtxt):

 

    # random.seed(int(time.time()))

    flag = random.uniform(0.5, 1.5) # flag > 1 means dimming, less than 1 means brightening

    label=round(flag,2)

    (filepath, tempfilename) = os.path.split(inputtxt)

    (filename, extension) = os.path.splitext(tempfilename)

    outputiamge=os.path.join(outputiamge+"/"+filename+"_"+str(label)+".jpg")

    outputtxt=os.path.join(outputtxt+"/"+filename+"_"+str(label)+extension)

 

    ima_gamma=exposure.adjust_gamma(img, 0.5)

 

    shutil.copyfile(inputtxt, outputtxt)

    cv.imwrite(outputiamge,ima_gamma)

 

# Add noise


def gasuss_noise(image,inputtxt,outputimage,outputtxt,mean=0, var=0.01):


'''


Add Gaussian noise


mean : mean


var : variance

    '''

    image = np.array(image/255, dtype=float)

    noise = np.random.normal(mean, var ** 0.5, image.shape)

    out = image + noise

 

    if out.min() < 0:

        low_clip = -1.

    else:

        low_clip = 0.

    out = np.clip(out, low_clip, 1.0)

    out = np.uint8(out*255)

 

    (filepath, tempfilename) = os.path.split(inputtxt)

    (filename, extension) = os.path.splitext(tempfilename)

    outputiamge = os.path.join(outputiamge + "/" + filename + "_gasunoise_" + str(mean)+"_"+str(var)+ ".jpg")

    outputtxt = os.path.join(outputtxt + "/" +  filename + "_gasunoise_" + str(mean)+"_"+str(var)+ extension)

 

    shutil.copyfile(inputtxt, outputtxt)

    cv.imwrite(outputiamge, out)

 

# Contrast Adjustment Algorithm


def ContrastAlgorithm(rgb_img,inputtxt, outputimag, outputtxt):


img_shape=rgb_img.shape


temp_imag=np.zeros(img_shape, dtype=float)


for num in range(0,3):


# Enhance contrast through histogram normalization


in_image =rgb_img[:,:,num]


# Calculate the maximum and minimum pixel values of the input image


Imax = np.max(in_image)


Imin = np.min(in_image)


# The minimum and maximum gray levels to output


Omin, Omax = 0, 255


# Calculate the values of a and b


a = float(Omax - Omin) / (Imax - Imin)


b = Omin - a * Imin


# Linear transformation of the matrix


out_image = a * in_image + b


# Data type conversion

       out_image = out_image.astype(np.uint8)

       temp_imag[:,:,num]=out_image

   (filepath, tempfilename) = os.path.split(inputtxt)

   (filename, extension) = os.path.splitext(tempfilename)

   outputiamge = os.path.join(outputiamge + "/" + filename + "_contrastAlgorithm"  + ".jpg")

   outputtxt = os.path.join(outputtxt + "/" + filename + "_contrastAlgorithm"  + extension)

   shutil.copyfile(inputtxt, outputtxt)

   cv.imwrite(outputiamge, temp_imag)

 

# rotate

def rotate_img_bbox(img, inputtxt,temp_outputiamge,temp_outputtxt,angle,scale=1):

    nAgree=angle

    size=img.shape

    w=size[1]

    h=size[0]

    for numAngle in range(0,len(nAgree)):

        dRot = nAgree[numAngle] * np.pi / 180

        dSinRot = math.sin(dRot)

        dCosRot = math.cos(dRot)

 

        nw = (abs(np.sin(dRot) * h) + abs(np.cos(dRot) * w)) * scale

        nh = (abs(np.cos(dRot) * h) + abs(np.sin(dRot) * w)) * scale

 

        (filepath, tempfilename) = os.path.split(inputtxt)

        (filename, extension) = os.path.splitext(tempfilename)

        outputiamge = os.path.join(temp_outputiamge + "/" + filename + "_rotate_" + str(nAgree[numAngle])+ ".jpg")

        outputtxt = os.path.join(temp_outputtxt + "/" + filename + "_rotate_" + str(nAgree[numAngle])+ extension)

 

        rot_mat = cv.getRotationMatrix2D((nw * 0.5, nh * 0.5), nAgree[numAngle], scale)

        rot_move = np.dot(rot_mat, np.array([(nw - w) * 0.5, (nh - h) * 0.5, 0]))

        rot_mat[0, 2] += rot_move[0]

        rot_mat[1, 2] += rot_move[1]


        # Affine transformation

        rotat_img = cv.warpAffine(img, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv.INTER_LANCZOS4)

        cv.imwrite(outputiamge,rotat_img)

 

        save_txt=open(outputtxt,'w')

        f = open(inputtxt)

        for line in f.readlines():

            line= line.split(" ")

            x1=float(line[0])

            y1=float(line[1])

            x2 = float(line[2])

            y2 = float(line[3])

            x3 = float(line[4])

            y3 = float(line[5])

            x4 = float(line[6])

            y4 = float(line[7])

            category=str(line[8])

 

            point1 = np.dot(rot_mat, np.array([x1, y1, 1]))

            point2 = np.dot(rot_mat, np.array([x2, y2, 1]))

            point3 = np.dot(rot_mat, np.array([x3, y3, 1]))

            point4 = np.dot(rot_mat, np.array([x4, y4, 1]))

            x1=round(point1[0],3)

            y1 = round(point1[1], 3)

            x2 = round(point2[0], 3)

            y2 = round(point2[1], 3)

            x3 = round(point3[0], 3)

            y3 = round(point3[1], 3)

            x4 = round(point4[0], 3)

            y4 = round(point4[1], 3)

            string = str(x1) + " " + str(y1) + " " + str(x2) + " " + str(y2) + " " + str(x3) + " " + str(

                y3) + " " + str(x4) + " " + str(y4)+" "+category

            save_txt.write(string)

 

def filp_pic_bboxes(img, inputtxt,outputiamge,outputtxt):

   

# ---------------------- Flip image ----------------------


    (filepath, tempfilename) = os.path.split(inputtxt)


    (filename, extension) = os.path.splitext(tempfilename)


    output_vert_flip_img = os.path.join(outputiamge + "/" + filename + "_vert_flip" + ".jpg")


    output_vert_flip_txt = os.path.join(outputtxt + "/" + filename + "_vert_flip" + extension)


    output_horiz_flip_img = os.path.join(outputiamge + "/" + filename + "_horiz_flip" + ".jpg")


    output_horiz_flip_txt = os.path.join(outputtxt + "/" + filename + "_horiz_flip" + extension)


 


    h,w,_ = img.shape




    #vertical flip    vert_flip_img = cv.flip(img, 1)


    cv.imwrite(output_vert_flip_img,vert_flip_img)




    # Flip horizontally


    horiz_flip_img = cv.flip(img, 0)


    cv.imwrite(output_horiz_flip_img,horiz_flip_img)


    # ---------------------- Adjust boundingbox ----------------------

 

    save_vert_txt = open(output_vert_flip_txt, 'w')

    save_horiz_txt = open(output_horiz_flip_txt, 'w')

    f = open(inputtxt)

    for line in f.readlines():

        line = line.split(" ")

        x1 = float(line[0])

        y1 = float(line[1])

        x2 = float(line[2])

        y2 = float(line[3])

        x3 = float(line[4])

        y3 = float(line[5])

        x4 = float(line[6])

        y4 = float(line[7])

        category = str(line[8])

 

        horiz_string = str(round(w-x1,3)) + " " + str(y1) + " " + str(round(w-x2,3)) + " " + str(y2) + " " + str(round(w-x3,3)) + " " + str(y3) + " " + str(

            round(w - x4, 3)) + " " + str(y4) + " " + category

        vert_string = str(x1) + " " + str(round(h-y1,3)) + " " + str(x2) + " " + str(round(h-y2,3)) + " " + str(x3) + " " + str(

            round(h - y3, 3)) + " " + str(x4) + " " + str(round(h-y4,3)) + " " + category

 

        save_horiz_txt.write(vert_string)

        save_vert_txt.write(horiz_string)

 

#Translate the image


def shift_pic_bboxes(img, inputtxt,outputiamge,outputtxt):


# ---------------------- Translate the image ----------------------


w = img.shape[1]


h = img.shape[0]


x_min = w # The smallest box containing all target boxes after cropping


x_max = 0


y_min = h


y_max = 0


f = open(inputtxt)


for line in f.readlines():


line = line.split(" ")


x1 = float(line[0])


y1 = float(line[1])


x2 = float(line[2])


y2 = float(line[3])


x3 = float(line[4])


y3 = float(line[5])


x4 = float(line[6])


y4 = float(line[7])


category = str(line[8])


x_min = min(x_min, x1,x2,x3,x4)


y_min = min(y_min, y1,y2,y3,y4)


x_max = max(x_max, x1,x2,x3,x4)


y_max = max(y_max, y1,y2,y3,y4)


d_to_left = x_min # Maximum leftward movement distance including all target boxes


d_to_right = w - x_max # Maximum rightward movement distance including all target boxes


d_to_top = y_min # Maximum upward movement distance including all target boxes


d_to_bottom = h - y_max # Maximum downward movement distance including all target boxes

    x = random.uniform(-(d_to_left - 1) / 3, (d_to_right - 1) / 3)

    y = random.uniform(-(d_to_top - 1) / 3, (d_to_bottom - 1) / 3)

 

    (filepath, tempfilename) = os.path.split(inputtxt)

    (filename, extension) = os.path.splitext(tempfilename)

    if x>=0 and y>=0 :

        outputiamge = os.path.join(outputiamge + "/" + filename + "_shift_" + str(round(x,3))+"_"+str(round(y,3)) + ".jpg")

        outputtxt = os.path.join(outputtxt + "/" + filename + "_shift_" + str(round(x,3))+"_"+str(round(y,3)) + extension)

    elif x>=0 and y<0:

        outputiamge = os.path.join(

            outputiamge + "/" + filename + "_shift_" + str(round(x, 3)) + "__" + str(round(abs(y), 3)) + ".jpg")

        outputtxt = os.path.join(

            outputtxt + "/" + filename + "_shift_" + str(round(x, 3)) + "__" + str(round(abs(y), 3)) + extension)

    elif x<0 and="" y="">=0:

        outputiamge = os.path.join(

            outputiamge + "/" + filename + "_shift__" + str(round(abs(x), 3)) + "_" + str(round(y, 3)) + ".jpg")

        outputtxt = os.path.join(

            outputtxt + "/" + filename + "_shift__" + str(round(abs(x), 3)) + "_" + str(round(y, 3)) + extension)

    elif x<0 and y<0:

        outputiamge = os.path.join(

            outputiamge + "/" + filename + "_shift__" + str(round(abs(x), 3)) + "__" + str(round(abs(y), 3)) + ".jpg")

        outputtxt = os.path.join(

            outputtxt + "/" + filename + "_shift__" + str(round(abs(x), 3)) + "__" + str(round(abs(y), 3)) + extension)

 

   c

    save_txt = open(outputtxt, "w")

    f = open(inputtxt)

    for line in f.readlines():

        line = line.split(" ")

        x1 = float(line[0])

        y1 = float(line[1])

        x2 = float(line[2])

        y2 = float(line[3])

        x3 = float(line[4])

        y3 = float(line[5])

        x4 = float(line[6])

        y4 = float(line[7])

        category = str(line[8])

        crop_str = str(round(x1-crop_x_min, 3)) + " " + str(round(y1-crop_y_min, 3)) + " " + str(round(x2-crop_x_min, 3)) + " " + str(\

            round(y2-crop_y_min, 3)) + " " + str(round(x3-crop_x_min, 3)) + " " + str(round(y3-crop_y_min, 3)) + " " + str(\

            round(x4-crop_x_min, 3)) + " " + str(round(y4-crop_y_min, 3)) + " " + category

        save_txt.write(crop_str)

 

if __name__=='__main__':

    inputiamge="./split_data_overlap512/agumnet_data/images"

    inputtxt = "./split_data_overlap512/agumnet_data/labels"

    outputiamge = "./split_data_overlap512/agumnet_data/images"

    outputtxt = "./split_data_overlap512/agumnet_data/labels"

    angle=[30,60,90,120,150,180]

    tempfilename=os.listdir(inputiamge)

    for file in tempfilename:

        (filename,extension)=os.path.splitext(file)

        input_image=os.path.join(inputiamge+"/"+file)

        input_txt=os.path.join(inputtxt+"/"+filename+".txt")

 

        img = cv.imread(input_image)

       

# Image brightness change


# changeLight(img, input_txt, outputiamge, outputtxt)


# Add Gaussian noise


# gasuss_noise(img, input_txt, outputiamge, outputtxt, mean=0, var=0.001)


# Change image contrast


# ContrastAlgorithm(img, input_txt, outputiamge, outputtxt)


# Image rotation


# rotate_img_bbox(img, input_txt, outputiamge, outputtxt, angle)


# Image mirroring


filp_pic_bboxes(img, input_txt, outputiamge, outputtxt)


# Translation


# shift_pic_bboxes(img, input_txt, outputiamge, outputtxt)


# Cropping


# crop_img_bboxes(img, input_txt, outputiamge, outputtxt)


    print("###finished!!!")


```

2. Model


The original RetinaNet paper, published at ICCV 2017, is titled "Focal Loss for Dense Object Detection." It was the first one-stage network to surpass a two-stage network, winning the best student paper award, despite not making any groundbreaking contributions to the network structure.

2.png

2.1 backbone 

The detailed structure of the RetinaNet network is shown below. Unlike FPN, which uses C2, RetinaNet does not, because P2 generated by C2 would consume more computational resources. Therefore, the authors directly started generating P3 from C3. The backbone part is basically similar to that of FPN, so the specific details will not be discussed further. The second difference lies in P6. The original paper generated it based on C5 (obtained by max pooling downsampling). Here, it is drawn according to the official PyTorch implementation, which uses 3 x 3 convolutional layers to achieve downsampling. The third difference is that FPN goes from P2 to P6, while RetinaNet goes from P3 to P7.

3.png

The figure above also shows the scales and ratios used from P3 to P7. In FPN, one scale and three ratios are used on each feature layer. In RetinaNet, there are three scales and three ratios, totaling 9 anchors. Note that here, the area of the anchor corresponding to a scale of 32 is the square of 32. Therefore, the smallest scale in RetinaNet is 32, and the largest is close to 813.


2.2 Predictor Section


Since RetinaNet is a one-stage network, ROI pooling is not used; instead, a weight-sharing convolution-based predictor is used directly, as shown in the figure below. The predictor is divided into two branches: predicting the class of each anchor and the regression parameters of the target bounding box. In the final kA, k is the number of target classes detected; note that k here does not include the background class, which is 20 for the PASCAL VOC dataset. A here is the number of anchors generated at each position of the predicted feature layer, which is 9 in this case. (Currently, most anchor regression parameter predictions are of this kind, which can also be understood as each class sharing the same anchor regression parameter predictor.)

4.png

2.3 Positive and Negative Sample Matching


For each anchor, it is compared with the pre-labeled ground truth boxes. If the IoU is greater than 0.5, it is a positive sample. If the IoU of an anchor with all ground truth boxes is less than 0.4, it is a negative sample. The rest are discarded.

5.png


2.4 Loss Calculation


A core contribution of this paper is the focal loss. The total loss is still divided into two parts: classification loss and regression loss. A unique aspect of focal loss is that the classification loss is calculated for both positive and negative samples, while the regression loss is calculated only for positive samples. Regression loss is explained in SSD and Faster R-CNN.

6.png

2.5 Focal Loss


To achieve a balanced ratio of positive to negative samples and prevent the entire training process from being "overwhelmed" by negative samples, a sampling method is generally used to control the ratio of positive to negative samples at 1:3, thus maintaining a reasonable proportion between positive and negative samples. Because one-stage training only has one phase, it generates far more candidate boxes than two-stage training. Typically, it requires approximately 100K locations (e.g., 8700+ locations in SSD), and among these, only a few (a dozen or so) are positive samples. Even with sampling, during the training process, you will still be surprised to find that the entire process is still dominated by a large number of easily distinguishable negative samples, i.e., the background. Focal loss is a dynamically scaled cross-entropy loss. In short, through a dynamic scaling factor, it can dynamically reduce the weight of easily distinguishable samples during training, thereby quickly focusing the loss on those difficult-to-distinguish samples (note: difficult-to-distinguish samples are not necessarily positive samples).

7.png

2.6 Cross Entropy Loss

The origin of Focal loss is binary cross-entropy (CE), which takes the following form::

8.png

In the above formula, y can take the values 1 and -1, representing foreground and background, respectively. p ranges from [0,1] and represents the probability of belonging to the foreground predicted by the model. For convenience, a value pt is defined.

9.png

Combining equations (1) and (2), we can obtain:

10.png


The CE curve is the blue curve in the figure below. As you can see, compared to other curves, the blue line changes the most smoothly. Even when p > 0.5 (which is already a well-distinguished sample), its loss is still high compared to other curves. Although it has decreased a lot compared to the previous ones, when the losses of a huge number of easily distinguishable samples are added together, it will dominate our training process. Therefore, we need to further increase the ratio of the magnitude of the losses before and after.

11.png

2.7 Balanced Cross Entropy

Balanced Cross Entropy is a common method for addressing class imbalance. Its idea is to introduce a weight factor α ∈ [0,1]. When the class label is 1, the weight factor is α; when the class label is -1, the weight factor is 1-α. For convenience, we use αt to represent the weight factor. The loss function is then rewritten as:

12.png

2.8 Calculation of Focal Loss


Balanced Cross Entropy addresses the imbalance between positive and negative examples, but it only balances the positive and negative samples without distinguishing between easy and hard examples. When easily distinguishable negative examples are abundant, the entire training process revolves around these examples (small losses accumulate and exceed large losses), while the hard-to-distinguish examples are neglected and become the focus of training. The authors introduce a new modulation factor, as shown in the following formula:

13.png

γ is also a parameter, ranging from [0,5]. Observing the above formula, we can see that when pt approaches 1, it indicates that the sample is relatively easy to distinguish, and the entire modulation factor (1-pt)^γ approaches 0, meaning the contribution of the loss is very small. If a sample is misclassified, pt is very small, then the modulation factor (1-pt)^γ approaches 1, which has no significant impact on the loss (relative to the basic cross-entropy). The parameter γ can adjust the rate of weight decay. As shown in the figure below, when γ = 0, $FL$ is the original cross-entropy loss CE. As γ increases, the adjustment rate also changes. Experiments show that the effect is best when γ = 2.

14.png

Combining positive/negative sample balance and easy/difficult sample balance, the final Focal loss form is as follows:


Its function can be interpreted as: αt suppresses the imbalance in the number of positive/negative samples, and γ controls the imbalance in the number of easy/difficult samples.


For Focal loss, the following can be summarized:


* For both foreground and background classes, the larger pt is, the smaller the weight (1-pt)^γ, meaning the loss of easy samples can be suppressed by the weights;


* αt is used to adjust the ratio between the losses of positive and negative samples. When αt is used for the foreground class, 1-αt is used for the corresponding background class;


* The optimal values of γ and αt are interdependent, so they need to be adjusted together when evaluating accuracy. The authors in the paper give that RetinaNet with ResNet-101+FPN as the backbone has the best performance when γ=2 and αt=0.25. Here, αt=0.25, with a small weight for positive samples and a large weight for negative samples, is beneficial for reducing the classification loss of negative samples, minimizing the loss of negative samples as much as possible.

 

3. Model Quantization


Model quantization is the process of converting a floating-point model to a fixed-point model using a certain method. For example, if the original model uses float32 weights, model quantization transforms it into a fixed-point model where all weights are ints.


3.1 Quantization Tool MOCA


This is a quantization tool developed based on mqbench, suitable for quantization in optical computing and for converting deployed ONNX models. The operators in the ONNX model are custom-defined operators executable by optical computing hardware, suitable for 8/4/3/2-bit fixed-point quantization.


3.2 Environment Dependencies


2. Environment Installation


1. This mainly involves installing the mmrotate repository and moca_cv (mqbench and omac). The specific package versions are as follows:

Package                                     Version                  Editable project location

--------------------------------    ------------                 ------------------------------

accimage                         0.2.0

addict                           2.4.0

aliyun-python-sdk-core           2.15.2

aliyun-python-sdk-kms            2.16.5

appdirs                          1.4.4

backports-datetime-fromisoformat  2.0.0

backports.weakref                1.0.post1

certifi                          2024.7.4

cffi                             1.17.1

charset-normalizer               3.3.2

click                            8.1.7

cmake                            3.21.0

colorama                         0.4.6

coloredlogs                      15.0.1

coverage                         7.4.3

crcmod                           1.7

cryptography                     43.0.1

cycler                           0.12.1

Cython                           3.0.0

e2cnn                            0.2.3

easydict                         1.9

et-xmlfile                       1.1.0

exceptiongroup                   1.2.1

filelock                         3.14.0

flatbuffers                      24.3.25

graphviz                         0.20.3

humanfriendly                    10.0

idna                             3.7

imageio                          2.9.0

importlib_metadata               8.5.0

iniconfig                        2.0.0

Jinja2                           3.1.4

jmespath                         0.10.0

joblib                           1.2.0

jsonpickle                       3.0.1

kiwisolver                       1.4.5

lgt_license                      1.2.3

lightning-utilities              0.11.7

llvmlite                         0.31.0

lvis                             0.5.3

Mako                             1.3.2

Markdown                         3.7

markdown-it-py                   3.0.0

MarkupSafe                       2.1.3

matplotlib                       3.3.3

mdurl                            0.1.2

mkl-fft                          1.3.8

mkl-random                       1.2.4

mkl-service                      2.4.0

mmcv                             2.0.0rc4

mmcv-full                        1.7.2

mmdet       2.28.2     /local/miniconda/envs/moca_cv/lib/python3.8/site-packages

mmengine                         0.10.4

mmrotate                         0.3.4        /root/dota_workspace/mmrotate

model-index                      0.1.11

mpmath                           1.3.0

MQBench 0.0.6        /root/workspace_moca_shankun_new/moca/QuantForCV/mqbench

networkx                         3.1

ninja                            1.11.1.1

numba                            0.48.0

numpy                            1.22.4

onnx                             1.16.0

onnxruntime                      1.19.2

onnxsim                          0.4.36

opencv-python                    4.1.2.30

opendatalab                      0.0.10

openmim                          0.3.9

openpyxl                         3.0.9

openxlab                         0.1.1

ordered-set                      4.1.0

osimulator                       1.2.3

oss2                             2.17.0

packaging                        24.0

pandas                           0.25.3

Pillow                           6.2.1

pip                              23.3.1

platformdirs                     3.10.0

pluggy                           1.5.0

prettytable                      3.10.0

protobuf                         3.20.3

psutil                           5.9.0

pycocotools                      2.0.7

pycparser                        2.22

pycryptodome                     3.18.0

pycuda                           2024.1

Pygments                         2.18.0

pyparsing                        3.1.2

pytest                           7.4.3

pytest-cov                       4.1.0

pytest-html                      4.0.2

pytest-metadata                  3.1.1

pytest-runner                    6.0.1

python-dateutil                  2.9.0.post0

pytools                          2024.1.6

pytz                             2023.4

PyWavelets                       1.4.1

PyYAML                           6.0.1

requests                         2.28.2

rich                             13.4.2

scikit-image                     0.19.3

scikit-learn                     1.3.2

scipy                            1.6.3

setuptools                       60.2.0

shapely                          2.0.6

SharedArray                      3.2.1

six                              1.16.0

sympy                            1.13.2

tabulate                         0.9.0

tensorboardX                     1.8

termcolor                        2.4.0

terminaltables                   3.1.10

threadpoolctl                    3.5.0

tifffile                         2023.7.10

tomli                            2.0.1

torch                            1.10.1+cu113

torchaudio                       0.10.1+cu113

torchmetrics                     1.4.1

torchvision                      0.11.2+cu113

tqdm                             4.65.2

typing_extensions                4.11.0

urllib3                          1.26.20

wcwidth                          0.2.13

wheel                            0.43.0

yapf                             0.40.2

zipp                             3.20.2


Note: Here, `mqbench` refers to the toolkit for installing MOCA.


3.3 Executing the Program


QAT quantization execution program, low-bit training and quantization


First, QAT needs to be configured in the `train.py` file located at `/root/dota_workspace/mmrotate/mmrotate/apis/train.py`.

15.png

16.png

17.png

QAT training script for 4-bit models:


CUDA_VISIBLE_DEVICES=0 python -u tools/train.py configs/


rotated_retinanet/rotated_retinanet_obb_r50_fpn_1x_dota_ms_rr_le90.py


--resume-from checkpoints


rotated_retinanet_obb_r50_fpn_1x_dota_ms_rr_le90-1da1ec9c.pth --work-dir logs/train_epoch_35/


> train_log_epoch35.log 2>&1 &


Configuration file:


rotated_retinanet_obb_r50_fpn_1x_dota_ms_rr_le90.py


Pre-trained model:


rotated_retinanet_obb_r50_fpn_1x_dota_ms_rr_le90-1da1ec9c.pth


Training log saving:


logs/train_epoch_35/


3.4 Training results


(1) For a 1024x1024 input:

18.png

(2)For  512x512 input:

19.png

4. Test Results on the Optical Computing Simulator


Inference Script Execution:


CUDA_VISIBLE_DEVICES=3 python -u tools/test_qat.py


configs/rotated_retinanet/ rotated_retinanet_obb_r50_fpn_1x_dota_ms_rr_le90.py


checkpoints/epoch_15.pth --eval mAP > test_alllayers.log 2>&1 &


4.1 For a 1024x1024 input, the Compass simulator was used.

20.png

4.2 For a 512x512 input,the Compass simulator was used.

21.png

4.3 For a 1024x1024 input ,the Compass simulator was used.

22.png

4.4 For a 512x512 input ,the Compass simulator was used.

23.png

4.5 Test visualization on the optical computing simulator

24.png

25.png