衛(wèi)星pos機(jī),深度學(xué)習(xí)應(yīng)用于太空衛(wèi)星對接

 新聞資訊  |   2023-03-10 08:54  |  投稿人:pos機(jī)之家

網(wǎng)上有很多關(guān)于衛(wèi)星pos機(jī),深度學(xué)習(xí)應(yīng)用于太空衛(wèi)星對接的知識,也有很多人為大家解答關(guān)于衛(wèi)星pos機(jī)的問題,今天pos機(jī)之家(www.afbey.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、衛(wèi)星pos機(jī)

2、pos數(shù)據(jù)全稱?

衛(wèi)星pos機(jī)

人工智能無處不在。家用電器、汽車、娛樂系統(tǒng),他們都包含AI功能。航天工業(yè)也不例外。

麥哲倫太空探測器用于繪制金星表面,使用Unity在地球軌道上模擬。

本文講解深度學(xué)習(xí)、神經(jīng)網(wǎng)絡(luò)和TensorFlow對衛(wèi)星對接所發(fā)揮的作用。

數(shù)據(jù)集準(zhǔn)備

了解衛(wèi)星的詳細(xì)尺寸,目標(biāo)是創(chuàng)建一種算法,可以準(zhǔn)確地預(yù)測其姿勢和相機(jī)的相對距離。該項目的數(shù)據(jù)集是從安裝在機(jī)器人手臂上的衛(wèi)星真實大小的模型中創(chuàng)建的。當(dāng)攝像機(jī)記錄視頻輸入時,手臂模擬各種動作。

由機(jī)器人手臂上的攝像機(jī)捕獲的衛(wèi)星模型

我決定集中精力尋找衛(wèi)星的尖端。如果我能準(zhǔn)確找到它,我有信心我可以對模型上的至少兩個其他標(biāo)簽做同樣的事情。鑒于這3個點和衛(wèi)星的3D模型,我可以重建衛(wèi)星的姿態(tài)和相對于攝像機(jī)的相對位置。

相機(jī)記錄了14424個未標(biāo)記的圖像,我想用它們來訓(xùn)練和評估神經(jīng)網(wǎng)絡(luò)。我擔(dān)心的一個問題是,我必須花費很多時間在每個圖像上手動標(biāo)記提示。幸運的是,我們可以使用OpenCV優(yōu)秀的圖像標(biāo)記工具:CVAT。

使用CVAT,你可以批量導(dǎo)入要注釋的所有圖像,將它們作為電影播放并插入相隔多幀的注釋。它還允許工作分散在多個人之間,甚至還有一個漂亮的docker-compose文件,只需點擊一下按鈕即可運行它。

CVAT節(jié)省了大量的時間和工作:只需花費幾個小時來注釋每個14,424圖像上的提示。對于衛(wèi)星的線性運動,我們只需要注釋開始和結(jié)束位置,CVAT將插入并添加其間的所有標(biāo)簽。如果你需要視頻或圖像注釋工具,強烈建議使用CVAT,

使用OpenCV CVAT中的方框注釋衛(wèi)星的尖端。

然而,有一些可改進(jìn)的地方。例如,CVAT不支持點之間的插值。作為解決方法,必須使用框來代替所有注釋的點。此外,任何未注釋的幀,即尖端不可見的幀,都不包含在XML輸出中。

<?xml version="1.0" encoding="utf-8"?><annotations><meta><!-- omitted --></meta><image id="0" name="20180727-OG3_04_45-camL0000.png" width="360px",height="auto" />

CVAT的XML輸出。

為了使此XML文件適合于訓(xùn)練和評估模型,必須將其后處理為正確的格式。有趣的是:這個看似微不足道的任務(wù),實際上需要相當(dāng)多的迭代來校對。我經(jīng)常不得不回去修改標(biāo)簽,添加新標(biāo)簽,更新輸出格式等等。

將原始數(shù)據(jù)和注釋轉(zhuǎn)換為適合訓(xùn)練和評估的數(shù)據(jù)集的代碼是代碼庫的重要組成部分。它不僅僅是一堆模糊的一次性終端命令。你應(yīng)該重視它,因為它允許你重現(xiàn)你的結(jié)果和文檔。版本化你的代碼,查看它,為你的數(shù)據(jù)集版本使用語義版本控制,最重要的是,讓處理相同問題的其他人通過壓縮并提供下載來輕松使用數(shù)據(jù)集。

數(shù)據(jù)集構(gòu)建腳本還允許使用不同版本的數(shù)據(jù)集進(jìn)行快速實驗:

應(yīng)用數(shù)據(jù)增強:旋轉(zhuǎn),模糊,銳化。嘗試不同的訓(xùn)練和評估分組。調(diào)整數(shù)據(jù)到適合你模型的表示。將數(shù)據(jù)轉(zhuǎn)換并打包成合適的格式。

最后一點值得關(guān)注。因為我正在使用Tensorflow,所以我想使用TFRecords數(shù)據(jù)格式。不僅因為它很好地集成到TF數(shù)據(jù)集API中,而且主要是因為我假設(shè)這種二進(jìn)制數(shù)據(jù)格式可以從磁盤中更有效地讀取。這是一個關(guān)于如何使用Python多處理將圖像和標(biāo)簽轉(zhuǎn)換為TFRecords文件的代碼摘錄。

import multiprocessing as mp

import tensorflow as tf

from skimage.io import imread

CPU_CORES = mp.cpu_count()

def write_tfrecords(labels, file):

with tf.io.TFRecordWriter(file) as tf_writer:

pool = mp.Pool(CPU_CORES)

for label in labels:

pool.apply_async(to_tf_records_example,

args=[label],

callback=lambda example: tf_writer.write(example),

error_callback=lambda exception: print("error converting to tfrecords example: {}".format(exception)))

pool.close()

pool.join()

def to_tf_records_example(label):

def _bytes_feature(values):

return tf.train.Feature(bytes_list=tf.train.BytesList(value=values))

def _float_feature(values):

return tf.train.Feature(float_list=tf.train.FloatList(value=values))

def _int64_feature(values):

return tf.train.Feature(int64_list=tf.train.Int64List(value=values))

name, (x, y) = label

img = os.path.join(BUILD_IMG_DIR, name + ".png")

img = imread(img, as_gray=True)

assert img.shape == (406, 528)

img = img.reshape([-1]) # flatten image into sequence of rows

example = tf.train.Example(features=tf.train.Features(feature={

"label": _int64_feature([round(float(x)), round(float(y))]),

"image": _int64_feature(img),

"name": _bytes_feature([(name + ".png").encode("utf-8")])

}))

return example.SerializeToString()

使用Python中的多處理將圖像和標(biāo)簽轉(zhuǎn)換為TFRecords文件。

在創(chuàng)建TFRecords文件之后,創(chuàng)建了這個腳本來進(jìn)行基準(zhǔn)測試并比較從TFRecords文件中讀取13,198個訓(xùn)練圖像所需的時間,而不是簡單地從磁盤讀取每個圖像并在運行中解碼它們。令人驚訝的是,TFRecords數(shù)據(jù)格式并沒有真正提高讀取訓(xùn)練數(shù)據(jù)集的速度。下面的定時輸出顯示從TFRecords文件順序讀取比從磁盤讀取每個圖像并在運行中解碼它們要慢。差異很小,但我絕對希望TFRecords更快。

如果你真的想要提高數(shù)據(jù)導(dǎo)入管道的性能,請考慮并行處理和預(yù)取數(shù)據(jù)。通過在解析數(shù)據(jù)集時簡單地設(shè)置tf.data.Dataset.map num_parallel_calls參數(shù),從TFRecords文件并行讀取這些相同的圖像比其順序讀取文件快2倍。從磁盤讀取每個圖像并在運行中解碼它們甚至快3倍。但是,在并行示例中,讀取TFRecords文件幾乎比在運行中讀取圖像慢2倍。

最后,結(jié)合并行解析和預(yù)取允許我在訓(xùn)練期間消除任何CPU瓶頸,并使用nvidia-smi命令測量的平均GPU利用率從75%增加到95%以上。

以下是在我的舊版iMac(2.7 GHz Intel Core i5)上運行時腳本的時序輸出:

順序解析13198圖像:TFRecords數(shù)據(jù)集:50.13s普通的PNG文件數(shù)據(jù)集:49.46s并行解析13198圖像:TFRecords數(shù)據(jù)集:26.78s普通的PNG文件數(shù)據(jù)集:15.96s模型原則

使用YOLO算法對物體檢測,如下所示。

使用YOLO進(jìn)行物體檢測

"YOLO是最有效的物體檢測算法之一,涵蓋了與物體檢測相關(guān)的整個計算機(jī)視覺文獻(xiàn)中的許多最佳創(chuàng)意。"

我將重點關(guān)注我如何使用YOLO來解決我的特定本地化問題。

Intermezzo - 對象分割,檢測和本地化。

對象分割,檢測和本地化之間存在差異。對象分割旨在找到各種形狀的片段,其給出要在圖像中檢測的對象的輪廓的像素方式描述。對象檢測是在給定圖像中的一個或多個對象周圍找到矩形邊界框的過程。對象定位是關(guān)于找到一個或多個對象的位置。

從左到右的對象分割,檢測和定位。

該算法的主要原理很簡單:獲取輸入圖像并應(yīng)用大量的卷積層,每個層都有自己的濾波器組。每組卷積層將減少圖像的特征空間或分辨率。請記住,卷積保留了空間局部性,因為每個層都與其相鄰層具有局部連接模式。因此,輸出層中的每個元素表示輸入處原始圖像的小區(qū)域。每個卷積步驟的濾波器可以在64到1024或甚至4096之間變化。然而,在最終輸出層中,濾波器的數(shù)量減少到3.換句話說,輸出層有3個通道,每個通道都將被訓(xùn)練為為圖像中特定區(qū)域的不同目的激活:

通道1 - 預(yù)測器位:表示在圖像的該區(qū)域中衛(wèi)星尖端存在的0和1之間的機(jī)會。通道2 - 相對X位置:尖端的垂直位置(如果可用),相對于該區(qū)域的左上角原點。通道3 - 相對Y位置:與通道2相同,但不同。

看看下面的圖片,這是我試圖描繪這個概念。

頂層中的輸入圖像在尺寸上減小到底部的輸出層。輸入和輸出層之間的灰線顯示沿深度維度的每個神經(jīng)元如何專用于圖像的特定區(qū)域。每個區(qū)域,輸出體積預(yù)測尖端是否可見,其X和Y坐標(biāo)是否相對于該區(qū)域的原點。在理想情況下,除了尖端可見的突出顯示的體積之外,預(yù)測將所有元素設(shè)置為零。

在我的第一個算法版本中,我沒有花很多時間來弄清楚什么是完美的CNN模型架構(gòu)來解決我的問題。相反,我想專注于代碼中允許我訓(xùn)練和評估模型的部分。因此,我只使用原始YOLO論文(下圖)實現(xiàn)了與建筑圖片相同的模型布局。

YOLO v1 CNN模型

這就是我的簡單思維將這些層解釋為代碼的方式。

def model(features, labels, mode, params):

is_training = (mode == tf.estimator.ModeKeys.TRAIN)

layer = conv_layer(features, is_training, filter_size=7, num_filters=64, strides=2, dropout_rate=params["dropout_rate"]) # (?, 200, 261, 64)

layer = tf.layers.max_pooling2d(layer, pool_size=2, strides=2) # (?, 100, 130, 64)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=192, strides=1, dropout_rate=params["dropout_rate"]) # (?, 100, 130, 192)

layer = tf.layers.max_pooling2d(layer, pool_size=2, strides=2) # (?, 50, 65, 192)

layer = conv_layer(layer, is_training, filter_size=1, num_filters=128, strides=1, dropout_rate=params["dropout_rate"]) # (?, 50, 65, 192)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=256, strides=1, dropout_rate=params["dropout_rate"]) # (?, 50, 65, 256)

layer = conv_layer(layer, is_training, filter_size=1, num_filters=256, strides=1, dropout_rate=params["dropout_rate"]) # (?, 50, 65, 256)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=512, strides=1, dropout_rate=params["dropout_rate"]) # (?, 50, 65, 512)

layer = tf.layers.max_pooling2d(layer, pool_size=2, strides=2) # (?, 25, 32, 512)

for _ in range(4):

layer = conv_layer(layer, is_training, filter_size=1, num_filters=256, strides=1, dropout_rate=params["dropout_rate"]) # (?, 25, 32, 256)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=512, strides=1, dropout_rate=params["dropout_rate"]) # (?, 25, 32, 512)

layer = conv_layer(layer, is_training, filter_size=1, num_filters=512, strides=1, dropout_rate=params["dropout_rate"]) # (?, 25, 32, 512)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=1024, strides=1, dropout_rate=params["dropout_rate"]) # (?, 25, 32, 1024)

layer = tf.layers.max_pooling2d(layer, pool_size=2, strides=2) # (?, 12, 16, 1024)

for _ in range(2):

layer = conv_layer(layer, is_training, filter_size=1, num_filters=512, strides=1, dropout_rate=params["dropout_rate"]) # (?, 12, 16, 512)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=1024, strides=1, dropout_rate=params["dropout_rate"]) # (?, 12, 16, 1024)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=1024, strides=1, dropout_rate=params["dropout_rate"]) # (?, 12, 16, 1024)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=1024, strides=2, dropout_rate=params["dropout_rate"]) # (?, 5, 7, 1024)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=1024, strides=1, dropout_rate=params["dropout_rate"]) # (?, 5, 7, 1024)

layer = conv_layer(layer, is_training, filter_size=3, num_filters=1024, strides=1, dropout_rate=params["dropout_rate"]) # (?, 5, 7, 1024)

layer = conv_layer(layer, is_training, filter_size=1, num_filters=4096, strides=1, dropout_rate=params["dropout_rate"]) # (?, 5, 7, 4096)

logits = conv_layer(layer, is_training, filter_size=1, num_filters=3, strides=1, dropout_rate=params["dropout_rate"]) # (?, 5, 7, 3)

def conv_layer(input, is_training, filter_size, num_filters, activation=tf.nn.relu, strides=1, dropout_rate=0.1):

padding = "same" if strides == 1 else "valid"

conv = tf.layers.conv2d(input, num_filters, filter_size, padding=padding, strides=strides, activation=activation) # (?, 32, 32, 32)

norm = tf.layers.batch_normalization(conv, training=is_training)

drop = tf.layers.dropout(norm, rate=dropout_rate, training=is_training) # (?, 32, 32, 32)

return drop

損失函數(shù)

為計算損失,我的第一步是將所有標(biāo)簽(基本上是衛(wèi)星尖端的x,y位置)轉(zhuǎn)換為輸出音量,如上圖所示。

代碼摘錄,將給定標(biāo)簽解析為類似于模型輸出的體積。

import tensorflow as tf

def parse_label(point, img_w, img_h, out_w, out_h):

block_dims = tf.constant([img_w/out_w, img_h/out_h]) # The width="360px",height="auto" />

offset_w, offset_h = tf.unstack(tf.floor(point/block_dims)) # Relative offset of the label in the output image.

point_x, point_y = tf.unstack((point % block_dims)/block_dims) # Get the part after the decimal point as a relative pos within a block.

offset_w, point_x = limit(offset_w, point_x, out_w) # Keep the point x and width="360px",height="auto" />

offset_h, point_y = limit(offset_h, point_y, out_h) # Keep the point y and height within the image boundaries.

point = tf.concat([[1.0], [point_x, point_y]], axis=0) # Add probability bit with value 1.0.

pixel = tf.reshape(point, [1, 1, 3]) # Reshape to a pixel in the output volume with 3 channels.

# Pad the pixel to the dimensions of the output.

return tf.image.pad_to_bounding_box(pixel, tf.to_int32(offset_h), tf.to_int32(offset_w), out_h, out_w)

def limit(offset, point, max):

return tf.cond(offset >= max, lambda: (max - 1.0, 1.0), lambda: (offset, point))

tf.InteractiveSession()

# For a label with x: 264 and y: 203 in a picture with w: 528 and h: 406, the following label would be produced if the output volume would be w: 7 and h: 5.

r = parse_label([264, 203], 528, 406, 7, 5)

tf.shape(r).eval()

# array([5, 7, 3], dtype=int32)

# All elements in the output are 0 except for this position:

r[2, 3, :].eval()

# array([1. , 0.4999999, 0.5000001], dtype=float32)

下一步是將給定的解析標(biāo)簽與模型的輸出進(jìn)行比較,并設(shè)置一個允許梯度下降來優(yōu)化模型參數(shù)的損失函數(shù)。我嘗試了很多替代方案,擺弄了均方誤差和均方對數(shù)誤差。最后,我決定使用交叉熵?fù)p失,因為它對于概率值在0和1之間的分類任務(wù)特別有效,就像預(yù)測損失一樣。

損失函數(shù)本身是兩部分的加權(quán)和:

預(yù)測損失:模型預(yù)測輸出量中每個盒子是否有衛(wèi)星尖端的程度。我給這個預(yù)測損失的權(quán)重為5,因為它是正確預(yù)測的主要貢獻(xiàn)者。XY損失:如果在該框中有一個模型,模型如何預(yù)測尖端的位置。如果圖中沒有可用的提示,則損失函數(shù)的這部分應(yīng)該為零,以便只有預(yù)測損失決定最終的損失。我給這個預(yù)測損失的權(quán)重為1。

看看下面實現(xiàn)這個損失函數(shù)的代碼。有了這個,我準(zhǔn)備使用Adam優(yōu)化器訓(xùn)練模型。

def get_loss(logits, labels, available):

"""

Calculate the loss from the output of the model and a given set of annotations or labels.

Args:

logits: a batch of model output volumes.

labels: a batch of labels.

available: boolean describing if there is a tip or not per image in a batch.

"""

batch_size = tf.shape(logits)[0]

pred_logits = logits[:, :, :, 0]

pred_labels = labels[:, :, :, 0]

pred_loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=pred_labels, logits=pred_logits)

weights = tf.reshape(tf.to_float(available), [batch_size, 1]) # If no points are available, only the probability bits determine the loss

xy_logits = tf.reshape(logits[:, :, :, 1:3], [batch_size, -1])

xy_labels = tf.reshape(labels[:, :, :, 1:3], [batch_size, -1])

xy_loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=xy_labels, logits=xy_logits, weights=weights)

return 5 * pred_loss + xy_loss

模型的損失函數(shù)。

這種損失特征仍然可以得到很大改善。如果圖像中有尖端,則計算輸出體積中每個框的XY損耗。這意味著對于沒有尖端可見的所有盒子也考慮了XY損失,這不是我想要的。因此,XY損失主要是訓(xùn)練以檢測背景而不是衛(wèi)星尖端。此外,XY損失不是像預(yù)測損失那樣的分類任務(wù)。因此,使用均方誤差或類似策略計算它可能更好。

遷移學(xué)習(xí)

一旦我有了模型和損失特征,正確運行和訓(xùn)練,我想換掉我對YOLO模型的解釋,用于經(jīng)過實戰(zhàn)考驗和預(yù)先訓(xùn)練的版本。由于我只有一個有限的數(shù)據(jù)集,我認(rèn)為需要遷移學(xué)習(xí)來解決問題。

一種選擇是簡單地從Tensorflow Hub中選擇一個模型。然而,TensorFlow使得使用這些模型變得太容易了,我想采取更具挑戰(zhàn)性的路線,以便我可以學(xué)到更多。我決定使用原作者的最新版YOLO模型,因為它是為Darknet編寫的,我想學(xué)習(xí)如何將該模型導(dǎo)入Tensorflow。

當(dāng)我開始研究最新的YOLO模型定義時,我很快意識到我需要解析并將該定義文件中的每個部分映射到正確的Tensorflow層。也許我應(yīng)該更加小心我所希望的,因為這是繁瑣而耗時的工作。幸運的是,我發(fā)現(xiàn)這個腳本將YOLO模型定義轉(zhuǎn)換為Keras模型,我可以使用Tensorflow加載。

遷移學(xué)習(xí)是關(guān)于重復(fù)使用在不同但相似的數(shù)據(jù)集上預(yù)訓(xùn)練的現(xiàn)有模型的部分層權(quán)重,并僅重新訓(xùn)練剩余的層。一旦我將所有252個模型層加載起來,我就必須弄清楚我想要保持不變的層(及其相關(guān)的權(quán)重),我想要重新訓(xùn)練的層以及它們的每個維度。在這個程度上,我寫了一個簡短的腳本,將Keras模型繪制成圖像,并根據(jù)給定的圖層列表計算尺寸。

使用此腳本,我可以簡單地預(yù)覽完整的模型布局,包括所有圖層名稱。然后我在模型的正中間手工挑選了一層:"add_19"。在我的實現(xiàn)中,使用layer.trainable屬性,前半部分中的所有層的權(quán)重保持不變,并且后半部分中的所有層的權(quán)重都被重新訓(xùn)練。模型中的最后一層是"conv2d_75",它有255個通道。我添加了一個額外的卷積層,內(nèi)核/濾波器大小為3,以減少并使模型輸出適合我的目標(biāo)最終尺寸。

在Keras中加載YOLO模型,啟用傳輸學(xué)習(xí)并匹配輸出層維度以匹配標(biāo)簽和損失函數(shù)。

K.set_learning_phase(1)m = load_model(params["model"], compile=False)m.load_weights(params["model"], by_name=True)m = Model(m.input, m.get_layer("conv2d_75").output) # Skip last layer (?, out_h, out_w, 255)for i, layer in enumerate(m.layers):if i == 152:assert layer.name == "add_19"layer.trainable = (i > 152)m = m(batch["image"])logits = tf.layers.conv2d(inputs=m, filters=3, kernel_size=1, strides=1, padding="same") # (?, out_h, out_w, out_c)loss = get_loss(logits, batch["label"], batch["available"])結(jié)果

首先,讓我們檢查遷移學(xué)習(xí)如何影響結(jié)果??纯聪旅娴膱D片。重新使用YOLO模型的前半部分并重新訓(xùn)練后半部分會產(chǎn)生巨大的差異。事實上,結(jié)果是無法比擬的。沒有遷移學(xué)習(xí),損失函數(shù)停滯在80左右,而通過遷移學(xué)習(xí),損失函數(shù)立即下降到幾乎為零。

每個訓(xùn)練步驟的模型損失函數(shù)輸出。深藍(lán)色線顯示沒有遷移學(xué)習(xí)的損失或僅僅是隨機(jī)初始化的模型。淺藍(lán)色線顯示模型的一半重用YOLO模型的權(quán)重時的損失。

以下圖片顯示了不使用傳輸學(xué)習(xí)時的模型輸出。注意模型如何能夠過濾掉背景并專注于提示,但永遠(yuǎn)無法做出準(zhǔn)確的預(yù)測。

不使用遷移學(xué)習(xí)時的模型預(yù)測輸出。模型的每個輸出體積顯示為半透明盒子,顏色范圍從(非常透明)藍(lán)色(表示該盒子中存在尖端的可能性很?。┑骄G色然后再變?yōu)榧t色(表示很高的機(jī)會) 。

當(dāng)不使用遷移學(xué)習(xí)時,模型預(yù)測輸出在42個訓(xùn)練時期內(nèi)針對相同圖像可視化。注意模型如何學(xué)習(xí)如何過濾背景,但從未成功縮小技巧。

這就是整個評估數(shù)據(jù)集的樣子,仍然沒有遷移學(xué)習(xí)。無需遷移學(xué)習(xí)的評估數(shù)據(jù)模型預(yù)測的視頻動畫。但是,這是整個評估數(shù)據(jù)集的樣子,啟用了傳輸學(xué)習(xí)。使用遷移學(xué)習(xí)對評估數(shù)據(jù)進(jìn)行模型預(yù)測的視頻動畫。很明顯,遷移學(xué)習(xí)是對結(jié)果產(chǎn)生巨大影響的。因此,本文的其余部分和結(jié)果假設(shè)啟用了遷移學(xué)習(xí)。

除了損失函數(shù)的輸出之外,模型的性能還有4種方式:

metrics / dist_mean:對于模型正確預(yù)測尖端存在的所有樣本,從預(yù)測到標(biāo)簽的平均距離(以像素為單位)是多少。accuracy / point_mean:對于模型正確預(yù)測尖端存在的所有樣本,這些樣本的百分比在距標(biāo)記的尖端10個像素內(nèi)。accuracy / prob_mean:模型能夠準(zhǔn)確預(yù)測尖端的存在。即預(yù)測器位必須高于0.5。accuracy / overall_mean:正確預(yù)測樣本的百分比。即如果沒有尖端,模型也預(yù)測相同,如果有尖端,則距離標(biāo)簽10個像素。

以下是在訓(xùn)練模型約8小時后,來自2885個樣品的評估數(shù)據(jù)集的評估結(jié)果。

metrics / dist_mean: 1.352pxaccuracy/ point_mean: 98.2%accuracy/ prob_mean: 98.7%accuracy/ overall_mean: 98.7%

你可以在下面看到Tensorboard中隨時間繪制的數(shù)字。簡單來說,算法平均偏離一個像素。

在8小時的訓(xùn)練期間,每個訓(xùn)練時期之后計算四個評估指標(biāo)和損失函數(shù)。

在2885個評估樣本中,32張圖片的預(yù)測已關(guān)閉。當(dāng)我看著它們時,28張是照片,其中檢測到的尖端的位置非常準(zhǔn)確,但模型根本沒有足夠的信心說有一個尖端。即預(yù)測位不超過0.5,但選擇了正確的方框。這是一個例子。

該模型預(yù)測尖端在10px內(nèi),但置信水平剛好低于0.5,因此它被標(biāo)記為錯誤的預(yù)測。它接近于0.5,當(dāng)舍入預(yù)測器位時,它恰好產(chǎn)生0.50。

剩下的四個負(fù)面預(yù)測更有趣。它們大部分被貼錯標(biāo)簽或至少含糊不清。當(dāng)尖端隱藏在對象后面但仍然容易讓人進(jìn)行本地化時,一些圖像被標(biāo)記為不一致。這正是模型捕獲的內(nèi)容。下面顯示了兩個示例:尖端隱藏在對象后面,并標(biāo)記為沒有可見的尖端。而模型預(yù)測有一個提示和正確的位置。

負(fù)面預(yù)測的示例,其中衛(wèi)星的尖端隱藏在對象后面。這些圖像被標(biāo)記為沒有可見的尖端(因此標(biāo)記為-1,-1),而模型仍然能夠預(yù)測正確的位置。

Intermezzo - Tensorflow估算器與手動抽象。

Tensorflow包括估算器,用于保護(hù)開發(fā)人員免受樣板代碼的影響,并將代碼引導(dǎo)到一個易于擴(kuò)展到多臺機(jī)器的結(jié)構(gòu)中。我總是使用估算器,并假設(shè)我對他們的忠誠會得到高效率,干凈的代碼和免費特征。在Tensorflow 1.12中,部分假設(shè)是正確的,但我仍然決定創(chuàng)建自己的抽象。下面我解釋一下原因。

為了確保一致性,每次調(diào)用估算器時,估算器都會從磁盤重新加載模型。{train(),predict(),evaluate()}。(train_and_evaluate方法只是一個用于調(diào)用estimator.train和estimator.evaluate的循環(huán)。)如果你有一個大型模型并且你想在同一臺機(jī)器上交錯訓(xùn)練和評估,那么重新加載模型真的會慢下來訓(xùn)練過程。

估算器重新加載模型的原因是為了確保分發(fā)模型時的一致性。這是他們背后的設(shè)計理念的重要組成部分,但正如你可以在這里看到的那樣,減速確實會引起挫折。此外,并非所有人都有需要或奢侈地?fù)碛蠫PU的大軍,或者更重要的是,他們需要時間來制作他們的模型,因為這需要仔細(xì)設(shè)計和努力。Tensorflow確實有一個InMemoryEvaluatorHook來克服這個問題。我試過它并且工作正常,但感覺更像是一種解決方法而不是真正的修復(fù)。

此外,當(dāng)我嘗試從估算器模型函數(shù)中加載我的Keras模型時,我花了一些時間才意識到必須在每列火車或評估呼叫后手動清除Keras模型。

這些東西并不是真正的顯示器,但是隨著學(xué)習(xí)Tensorflow如何工作的沖動,它們足以說服我創(chuàng)建自己的微抽象。

隨著Tensorflow 2.0的出現(xiàn),我相信我所掙扎的大部分內(nèi)容都將得到解決。Keras將集成到Tensorflow的核心,并成為其主要接口之一。估算器仍然是首選。

經(jīng)驗教訓(xùn)

以下是我學(xué)到的一些可能對你有用的總結(jié):

雙重,三重和四重檢查評估/訓(xùn)練指標(biāo)的語義,解釋和正確性。例如,我的模型從一開始就獲得了100%的準(zhǔn)確率。這不是因為該模型非常準(zhǔn)確,而是因為該度量僅考慮了模型正確預(yù)測的那些樣本,所以存在提示。如果10000個中只有5個樣本檢測到正確的尖端,則100%的準(zhǔn)確度仍然意味著在10px內(nèi)僅檢測到5個圖像。特別是tf.metrics API騙了我不止一次。明智地使用tf.metrics。它們用于評估,即通過多個批處理操作和整個評估數(shù)據(jù)集聚合結(jié)果。務(wù)必在適當(dāng)?shù)臅r候重置他們的狀態(tài)。如果你在Tensorflow中使用批量規(guī)范,請不要忘記在訓(xùn)練期間更新移動均值和方差。這些更新操作自動存儲在tf.GraphKeys.UPDATE_OPS集合中,因此不要忘記運行它們。

# Example using tf.control_dependencies:

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)

with tf.control_dependencies(update_ops):

train_op = optimiser.minimize(loss)

# Example using tf.group:

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)

minimize = optimizer.minimize(loss)

train_op = tf.group([minimize, update_ops])

關(guān)于在Tensorflow中執(zhí)行批量規(guī)范時如何更新移動均值和方差的兩個代碼示例。將單元測試寫為完整性檢查或至少將快速和臟的測試腳本保存到單獨的文件中以供以后參考。徹底測試損失函數(shù)尤其有意義。每次訓(xùn)練模型時,請確保將所有輸出指標(biāo)和其他數(shù)據(jù)保存到唯一的,帶時間標(biāo)記的目錄中。另外,存儲git標(biāo)簽(例如heads / master-0-g5936b9e)。這樣,無論何時搞砸模型,它都會幫助你恢復(fù)到之前的工作版本。

有關(guān)如何將git描述寫入文件的示例代碼。

def write_git_description(dir):

mkdir(dir)

fnull = open(os.devnull, "w")

cmd = "git describe --all --long > {}/git-description".format(dir)

subprocess.call(cmd, shell=True, stdout=fnull, stderr=fnull)

view raw

將你的指標(biāo)寫入Tensorboard,用于訓(xùn)練和評估。這是非常值得的,因為可視化可以讓你深入了解工作表現(xiàn)。它有一些挑戰(zhàn),但作為回報,你可以更快地迭代和測試你的想法。跟蹤TensorBoard中的所有可訓(xùn)練變量,以幫助你盡早檢測爆炸或消失的梯度。以下是關(guān)于如何做到這一點的一些靈感。

關(guān)于如何可視化模型中每個可訓(xùn)練變量的平均值和直方圖以及所有可訓(xùn)練變量的總體直方圖的示例代碼。

嘗試自動并定期暫停訓(xùn)練過程以評估模型。務(wù)必將訓(xùn)練曲線和評估曲線渲染到Tensorboard中的相同圖形。這樣,你可以將模型的性能可視化為在訓(xùn)練過程中從未見過的數(shù)據(jù),并在你發(fā)現(xiàn)問題時立即停止。請注意,只需重復(fù)使用相同的標(biāo)記,就無法在同一個圖中顯示多個摘要。Tensorboard將通過在標(biāo)簽名稱中添加"_1"來自動使這些摘要唯一,從而強制它們顯示在單獨的圖中。如果要解決此限制,可以自己生成摘要協(xié)議緩沖區(qū),然后手動將它們添加到summary.FileWriter()

有關(guān)如何在評估期間使用標(biāo)記"metrics / loss"保存度量標(biāo)準(zhǔn)的示例,同時在訓(xùn)練期間使用具有完全相同標(biāo)記的度量標(biāo)準(zhǔn)。這允許將訓(xùn)練和評估曲線顯示在Tensorboard中的同一圖表上。

監(jiān)控GPU利用率和內(nèi)存消耗,并盡可能提高GPU利用率。如果你使用NVIDIA顯卡,則可以使用nvidia-smi命令來執(zhí)行此操作。你還可以使用htop監(jiān)控CPU和內(nèi)存消耗。所用硬件列表

· NVIDIA Geforce RTX2080TI(11GB,4352 Cuda核心,600W,INNO3D GAMING OC X3)

· Supermicro X9DRG-QF雙CPU主板

· 2x Intel Xeon E5-2630(12核)

· 三星860 EVO SD(500G)

· 128G內(nèi)存

pos數(shù)據(jù)全稱?

POS數(shù)據(jù)是定位定姿系統(tǒng),是IMU/DGPS組合的高精度位置與姿態(tài)測量系統(tǒng)(position and orientation system,POS)。利用裝在飛機(jī)上的GPS接收機(jī)和設(shè)在地面上的一個或多個基站上的GPS接收機(jī)同步而連續(xù)地觀測GPS衛(wèi)星信號。

精密定位主要采用差分GPS定位(DGPS)技術(shù),而姿態(tài)測量主要是利用慣性測量裝置(IMU)來感測飛機(jī)或其他載體的加速度,經(jīng)過積分運算,獲取載體的速度和姿態(tài)等信息

以上就是關(guān)于衛(wèi)星pos機(jī),深度學(xué)習(xí)應(yīng)用于太空衛(wèi)星對接的知識,后面我們會繼續(xù)為大家整理關(guān)于衛(wèi)星pos機(jī)的知識,希望能夠幫助到大家!

轉(zhuǎn)發(fā)請帶上網(wǎng)址:http://www.afbey.com/news/6956.html

你可能會喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 babsan@163.com 舉報,一經(jīng)查實,本站將立刻刪除。