manycore-research/PlankAssembly | DeepWiki
PlankAssembly項目原理
這個項目是一個基于深度學習的3D重建系統,其核心原理是從三個正交視圖的工程圖紙中重建出3D形狀的結構化程序表示。
核心技術原理
1. 問題定義
PlankAssembly旨在從三個正交視圖的工程圖紙中進行魯棒的3D重建,使用學習到的形狀程序來表示3D結構?README.md:3?。項目支持三種類型的輸入:可見和隱藏線條、僅可見邊緣、以及側面視圖?README.md:38?。
2. 模型架構
項目采用了基于Transformer的序列到序列(Sequence-to-Sequence)架構:
- 編碼器-解碼器結構:使用標準的Transformer編碼器和解碼器來處理輸入線條序列并生成輸出形狀程序?models.py:59-69
TransformerEncoderLayer 在 PlankModel 中的使用
在 PlankAssembly 系統中,TransformerEncoderLayer
?是從 PyTorch 導入的標準 Transformer 編碼器層,用于構建?PlankModel
?的編碼器部分。?models.py:7-8
具體實現中,TransformerEncoderLayer
?在?PlankModel
?的初始化過程中被配置:?models.py:60-63
這里創建了一個編碼器層,配置了以下參數:
num_model
: 隱藏維度 (默認 512)num_head
: 多頭注意力頭數 (默認 8)num_feedforward
: 前饋網絡維度 (默認 1024)dropout
: Dropout 率activation
: 激活函數normalize_before
: 是否在注意力前進行層歸一化batch_first=True
: 批次維度在第一位
在訓練系統中的作用
這個?TransformerEncoderLayer
?是整個訓練系統的核心組件,通過?build_model(cfg)
?函數在訓練器中被實例化。?trainer_complete.py:29
訓練過程中,編碼器處理輸入的 2D 線條數據序列,為后續的解碼器生成 3D 邊界框預測提供編碼表示。
Notes
TransformerEncoderLayer
?是 PyTorch 標準庫的組件,在這個項目中被用作 PlankModel 架構的編碼器部分。該模型支持多種輸入模態(完整線條、可見線條、側面數據),都使用相同的 Transformer 編碼器架構進行處理。
- 多模態嵌入:輸入序列包含多種信息維度的嵌入,包括數值、位置、坐標、視圖和類型信息?models.py:47-53
3. 輸入表示
輸入的工程圖紙被轉換為結構化的線條序列:
- 每條線段用4個自由度表示(x1, y1, x2, y2坐標)?line_data.py:36-46
- 線條按視圖和坐標進行排序,并添加位置、視圖和類型等元信息?line_data.py:41-58
4. 輸出表示
輸出是量化的3D形狀程序,每個"板塊"(plank)用6個自由度的邊界框表示?models.py:25?。輸出序列經過量化處理并添加特殊標記?line_data.py:87-94?。
5. 指針網絡機制
項目的一個關鍵創新是使用了指針網絡(Pointer Network)機制:
- 詞匯表分布:用于生成新的token
- 指針分布:用于指向之前生成的序列元素
- 切換機制:動態決定是從詞匯表采樣還是使用指針?models.py:72-74
這種機制使模型能夠處理結構化輸出中的依賴關系和引用關系?models.py:140-188?。
6. 訓練和推理
- 訓練階段:使用teacher forcing,同時計算詞匯表損失和指針損失?models.py:190-233
def train_step(self, batch):"""Pass batch through plank model and get log probabilities under model."""inputs = {key:value for key, value in batch.items() if key[:5]=='input'}input_mask = batch['input_mask']output_value = batch['output_value']output_label = batch['output_label']output_mask = batch['output_mask']# embed inputinput_embeds = self._embed_input(inputs)# embed outputoutput_embeds = self._embed_output(output_value[:, :-1])memory = self.encoder(input_embeds, src_key_padding_mask=input_mask)# tgt masktgt_mask = self._generate_square_subsequent_mask(output_embeds.size(1)).to(input_embeds.device)# pass through decoderhiddens = self.decoder(output_embeds, memory, tgt_mask=tgt_mask,tgt_key_padding_mask=output_mask,memory_key_padding_mask=input_mask)# create categorical distributiondists = self._create_dist(hiddens)logits = dists.transpose(1, 2)loss = F.nll_loss(logits, output_label, ignore_index=self.token.PAD)predict = torch.argmax(logits, dim=1)valid = output_label != self.token.PADcorrect = (valid * (predict == output_label)).sum()accuracy = float(correct) / (valid.sum() + 1e-10)rets = {}rets['loss'] = lossrets['accuracy'] = accuracyreturn rets
- 推理階段:采用自回歸生成,逐步構建輸出序列直到遇到結束標記?models.py:267-323
def eval_step(self, batch):"""Autoregressive sampling."""inputs = {key:value for key, value in batch.items() if key[:5]=='input'}input_mask = inputs['input_mask']# embed inputsinput_embeds = self._embed_input(inputs)batch_size = len(input_embeds)device = input_embeds.devicememory = self.encoder(input_embeds, src_key_padding_mask=input_mask)output = torch.empty((batch_size, 0), dtype=torch.long, device=device)attach = torch.empty((batch_size, 0), dtype=torch.long, device=device)for _ in range(self.max_output_length):# embed decoder inputsoutput_embeds = self._embed_output(output)# tgt masktgt_mask = self._generate_square_subsequent_mask(output.size(1)+1).to(device)# pass through decoderhiddens = self.decoder(output_embeds, memory, tgt_mask=tgt_mask,memory_key_padding_mask=input_mask)# create categorical distributiondists = self._create_dist(hiddens)# sample from the distributionnext_output, next_attach = self._sample(dists, output)# update samplesoutput = torch.concat((output, next_output), dim=1)attach = torch.concat((attach, next_attach), dim=1)if torch.all(torch.any(output == self.token.END, dim=1)):breakpredicts, groundtruths = [], []for i in range(batch_size):predict = self.parse_sequence(output[i])groundtruth = self.parse_sequence(batch['output_value'][i])predicts.append(predict)groundtruths.append(groundtruth)rets = {}rets['samples'] = outputrets['attach'] = attachrets['predicts'] = predictsrets['groundtruths'] = groundtruthsreturn rets
技術特點
- 魯棒性:支持噪聲輸入和不完整的線條信息
- 結構化輸出:直接生成可執行的3D形狀程序而非點云或網格
- 多視圖融合:有效整合來自三個正交視圖的信息
- 端到端學習:從原始線條到3D形狀程序的直接映射
Notes
PlankAssembly項目代表了將傳統工程制圖與現代深度學習技術結合的創新嘗試。通過將3D重建問題轉化為序列生成問題,并引入指針網絡機制處理結構化約束,該方法在工程圖紙理解方面取得了顯著進展。項目還有后續工作CAD2Program,進一步探索了視覺Transformer在工程圖紙理解中的應用
您詢問的是PlankAssembly系統的輸入數據和輸出數據格式。基于代碼分析,我來詳細說明這個3D重建系統的數據流。
輸入數據
PlankAssembly系統支持三種輸入數據類型,都是從三視圖工程圖轉換而來:
1. 完整線條數據 (Complete Lines)
包含可見線和隱藏線的完整工程圖?README.md:85-86
2. 可見線條數據 (Visible Lines)
僅包含可見邊緣的工程圖?README.md:89-90
3. 側面多邊形數據 (Sideface Data)
提取的面多邊形數據
輸入數據的具體格式在LineDataset
中處理,包含:
- 線條坐標?(
lines
): 線段的邊界框坐標 - 視圖信息?(
views
): 標識線條屬于哪個視圖(正視圖、俯視圖、側視圖) - 類型信息?(
types
): 線條的類型標識?line_data.py:121-123
輸出數據
系統輸出3D形狀程序,包含兩個主要組件:
1. 3D幾何坐標 (Planks)
表示3D模型中每個木板的幾何參數,包含6個值(位置和尺寸信息)?line_data.py:125
2. 連接信息 (Attach)
描述木板之間的連接關系和約束?line_data.py:126
輸出序列經過量化處理并添加特殊標記:
- 添加停止標記 (
END token
) - 添加填充標記 (
PAD token
) - 生成對應的標簽和掩碼?line_data.py:87-107
數據處理流程
整個數據流程如下:
- 3D形狀程序?(JSON格式) →?SVG渲染?→?三視圖SVG文件
- SVG文件?+?形狀程序?→?JSON信息文件?(通過
prepare_info.py
) - 訓練時: JSON信息文件 →?序列化輸入/輸出?→?模型訓練?README.md:93-97
Notes
系統使用PythonOCC進行三視圖正交工程圖渲染?README.md:82?,支持噪聲注入進行數據增強?README.md:87-88?。輸出的3D形狀程序可以進一步轉換為STL網格文件用于可視化。
您詢問的是關于PlankAssembly系統中SVG渲染系統的數據處理流程。SVG不是像素數據,而是矢量圖形格式,用于表示3D模型的正交工程圖。
SVG渲染系統概述
PlankAssembly使用SVG(可縮放矢量圖形)格式來表示從3D模型生成的三視圖工程圖。這些SVG文件包含線條幾何信息,而不是像素數據。?README.md:82
數據處理流程
1. SVG渲染腳本
系統提供三種不同的SVG渲染腳本來處理原始3D模型:
render_complete_svg.py
?- 渲染完整輸入(可見線和隱藏線)?README.md:85-86render_visible_svg.py
?- 僅渲染可見線?README.md:89-90render_noisy_svg.py
?- 渲染帶噪聲的輸入?README.md:87-88
2. SVG數據結構
生成的SVG文件以GeoJSON格式存儲線條幾何信息,包含:
- 線條坐標邊界框 [x_min, y_min, x_max, y_max]
- 視圖索引(0=正視圖,1=俯視圖,2=側視圖)
- 線條類型分類?line_data.py:119-123
3. 數據打包
使用prepare_info.py
將SVG文件和形狀程序打包成JSON格式:?README.md:96
SVG vs 像素數據
SVG是矢量格式,存儲的是幾何線條信息,具有以下特點:
- 可無限縮放而不失真
- 存儲線條的數學描述而非像素點
- 適合工程圖的精確表示
這與像素/柵格圖像完全不同,后者存儲固定分辨率的像素陣列。
Notes??注釋
PlankAssembly系統專門設計用于處理矢量化的工程圖,因為這種格式能夠精確表示3D模型的幾何特征。系統還支持柵格圖像輸入,但需要切換到不同的分支(raster branch)。
{"name": "MH2AYXIKTEMTEAABAAAAAAA8_2","id": "bcfce7f1-61c7-11ed-8fb6-5a377d2e67eb","planks": [[-1050.0000732051035,-290.0,-1000.0000006588434,1050.0000732051035,290.0,1000.0000006588434],[-1050.0000732051035,-290.0,-999.9999993411515,-1031.9999267948967,290.0,999.9999993411516],[1011.9999267948965,-270.0,-999.9999993411515,1030.0000732051035,290.0,999.9999993411516],[-1031.99995613098,-270.0,982.0,1012.0000438690199,290.0,1000.0],[1031.9999267948965,-290.0,-999.9999993411515,1050.0000732051035,-230.0,999.9999993411516]],"normal": [[0.0,0.0,1.0],[-1.0,0.0,-0.0],[-1.0,0.0,-0.0],[0.0,0.0,1.0],[-1.0,0.0,-0.0]],"attach": [[-1,-1,-1,-1,-1,-1],[0,1,2,-1,4,5],[-1,-1,2,-1,4,5],[9,-1,-1,12,4,5],[-1,1,2,3,-1,5]]
}
這是PlankAssembly系統中的3D形狀程序(shape program)數據格式,用于表示由多個木板(planks)組成的3D模型。
數據結構解析
這個JSON文件包含了一個3D模型的完整描述:
基本信息
name
: 模型的唯一標識符 "MH2AYXIKTEMTEAABAAAAAAA8_2"id
: 數據庫ID "bcfce7f1-61c7-11ed-8fb6-5a377d2e67eb"
planks 數組
每個木板用6個浮點數表示邊界框坐標?[x_min, y_min, z_min, x_max, y_max, z_max]
:
- 第1個木板: 大型底板,從(-1050, -290, -1000)到(1050, 290, 1000)
- 第2-5個木板: 較小的連接板和支撐板?line_data.py:125-126
normal 數組??標準數組
每個木板的法向量,表示木板的朝向:
[0, 0, 1]
: Z軸正方向(水平放置)[-1, 0, 0]
: X軸負方向(垂直放置)
attach 數組??附加數組
這是關鍵的連接信息,用于transformer模型的指針機制。每個木板有6個連接點,值表示:
-1
: 無連接- 數字: 連接到其他木板的特定坐標索引?line_data.py:98-101
在訓練流程中的作用
這種數據格式在PlankAssembly系統中的處理流程:
-
輸入準備:?
planks
數組被展平并量化為離散token?line_data.py:87 -
指針機制:?
attach
數組用于創建標簽,指針索引會加上詞匯表大小的偏移?line_data.py:100 -
模型訓練: transformer模型學習從2D工程圖重建這種3D形狀程序
數據特點
- 精確性: 使用浮點坐標確保幾何精度
- 結構化: 標準化的6D邊界框表示
- 連接性: attach數組編碼了木板間的裝配關系
- 可擴展: 支持任意數量的木板組合
Notes??注釋
這是PlankAssembly系統的核心數據表示,與SVG渲染的2D線條數據形成輸入-輸出對。系統的目標是從2D工程圖學習重建這種結構化的3D表示。每個數值的精度反映了工程制造的要求。
您詢問的是PlankAssembly系統中attach數組里的數字12的含義。
attach數組中的指針索引
在您提供的例子中,[9, -1, -1, 12, 4, 5]
是第4個木板的attach數組。這個數組表示該木板6個連接點的連接狀態:
- 位置0: 指向索引9的坐標
- 位置1-2: 無連接(-1)
- 位置3:?指向索引12的坐標
- 位置4-5: 指向索引4和5的坐標
指針機制的工作原理
數字12是一個指針索引,指向展平后的坐標序列中的第12個位置。在訓練過程中,這些指針會被轉換為模型的標簽:?line_data.py:100
當attach
數組中的值不等于-1時,系統會給這些指針索引加上詞匯表大小(vocab_size
)的偏移,將其轉換為特殊的指針token。
坐標索引的計算
由于每個木板用6個坐標值表示[x_min, y_min, z_min, x_max, y_max, z_max]
,索引12對應:
- 木板索引: 12 ÷ 6 = 2 (第3個木板)
- 坐標分量: 12 % 6 = 0 (該木板的x_min坐標)
所以數字12指向第3個木板的x_min坐標值,表示當前木板的第4個連接點與第3個木板的左邊界相連。
在模型訓練中的作用
這種指針機制讓transformer模型能夠學習木板之間的裝配關系:?line_data.py:98-101
模型通過這些指針標簽學會在生成3D形狀程序時正確建立木板間的連接關系。
Notes??注釋
這是PlankAssembly系統核心的指針機制,使模型能夠處理結構化的3D裝配任務。每個非-1的數值都代表一個具體的幾何連接點,12只是其中一個指向特定坐標的索引。
您詢問的是PlankAssembly系統中連接指針(attach指針)機制的作用和必要性。
連接指針的核心作用
連接指針機制是PlankAssembly系統解決結構化3D重建問題的關鍵創新。它讓transformer模型能夠學習和生成具有正確裝配關系的3D形狀程序。
為什么需要指針機制
1. 解決裝配約束問題
在3D木板裝配中,木板之間必須有精確的連接關系。傳統的序列生成無法表達這種幾何約束,而指針機制通過直接引用坐標索引來建立連接:?line_data.py:100-101
當attach
數組中的值不等于-1時,系統給指針索引加上vocab_size
偏移,將其轉換為特殊的指針token,使模型能夠區分普通坐標token和連接指針。
2. 實現精確的幾何連接
指針機制讓模型能夠精確指定木板間的連接點。例如,索引12指向第3個木板的x_min坐標,表示當前木板與該坐標位置相連。這種精確性對于生成可制造的3D模型至關重要。
3. 支持復雜裝配結構
通過指針機制,模型可以處理任意復雜的裝配關系:
- 一個木板可以連接到多個其他木板
- 連接可以指向任意坐標分量(x_min, y_min, z_min, x_max, y_max, z_max)
- 支持層次化的裝配結構
在訓練和推理中的作用
訓練階段line_data.py:98-101
模型學習預測正確的指針索引,建立輸入2D線條與輸出3D裝配關系的映射。
推理階段trainer_complete.py:97-106
模型生成的指針信息被用于構建最終的3D形狀程序,確保木板間的連接關系正確。
與傳統方法的對比
如果沒有指針機制,模型只能生成獨立的木板坐標,無法表達裝配約束。指針機制使PlankAssembly能夠:
- 保證幾何一致性?- 連接的木板在指定位置必須對齊
- 支持結構化輸出?- 生成的不是簡單的坐標列表,而是帶有裝配關系的結構化程序
- 實現端到端學習?- 從2D工程圖直接學習到3D裝配關系
Notes??注釋
這種指針機制是PlankAssembly系統的核心創新,使其能夠處理結構化的3D重建任務。它將傳統的序列到序列問題轉化為帶有結構約束的生成問題,這對于工程應用中的精確裝配至關重要。
在PlankAssembly的PlankModel
中,輸入數據經過embedding后會被轉換為多維特征表示。
Embedding組件結構
模型使用多模態embedding系統,包含5個不同的embedding層:?models.py:47-53
每個embedding層的作用:??每個 embed
input_value
: 量化后的坐標值embeddinginput_pos
: 序列位置embeddinginput_coord
: 坐標類型embedding (x/y坐標標識)input_view
: 視圖embedding (正視圖/俯視圖/側視圖)input_type
: 線條類型embedding (可見線/隱藏線)
輸入數據預處理
在LineDataset
中,原始線條數據被處理成embedding所需的格式:?line_data.py:34-83
處理步驟包括:
- 坐標量化為離散token
- 按視圖和坐標排序
- 添加位置、坐標類型、視圖、線條類型標識
- 添加END和PAD token進行填充
Embedding后的格式
經過embedding處理后,每個輸入token被轉換為num_model
維度(默認512維)的向量表示。最終的輸入格式是一個字典:
inputs = { 'input_value': [batch_size, max_input_length], # 量化坐標值 'input_pos': [batch_size, max_input_length], # 位置索引 'input_coord': [batch_size, max_input_length], # 坐標類型 'input_view': [batch_size, max_input_length], # 視圖索引 'input_type': [batch_size, max_input_length], # 線條類型 'input_mask': [batch_size, max_input_length] # 填充掩碼 }
每個embedding層將對應的索引轉換為512維向量,然后這些向量會被相加形成最終的輸入表示,送入transformer encoder。
Notes??注釋
這種多模態embedding設計讓模型能夠同時理解坐標值、空間位置、幾何類型和視圖信息,為從2D線條重建3D結構提供了豐富的特征表示。所有embedding維度都統一為num_model
(512),便于后續的transformer處理。
您詢問的是PlankAssembly系統中將輸入數據轉換為512維embedding向量的具體代碼實現。
Embedding定義代碼
在PlankModel的初始化中,定義了5個embedding層,每個都將離散索引映射到512維向量:?models.py:47-53
這里num_model=512
是配置參數,定義了embedding的輸出維度。
去學embedding了
PlankAssembly系統的輸入和輸出數據格式不一致,它們代表完全不同的數據類型:
輸入數據格式
輸入是2D線條數據,經過預處理后包含:
input_value
: 量化后的坐標值序列input_pos
: 位置索引input_coord
: 坐標類型標識input_view
: 視圖索引(0=正視圖,1=俯視圖,2=側視圖)input_type
: 線條類型(可見線/隱藏線)
輸出數據格式
輸出是3D形狀程序,包含:
output_value
: 量化后的3D邊界框坐標序列output_label
: 帶指針機制的標簽序列output_mask
: 填充掩碼?sideface_data.py:207-213
關鍵差異
- 數據維度不同: 輸入是2D線條(4維坐標),輸出是3D邊界框(6維坐標)
- 語義不同: 輸入表示工程圖線條,輸出表示3D木板裝配
- 結構不同: 輸出包含指針機制用于表達裝配關系,輸入沒有
您詢問的是PlankAssembly系統中2D線條輸入數據的具體格式。讓我通過代碼示例來說明這種格式。
2D線條數據的原始格式
在PlankAssembly中,輸入的2D線條數據來自SVG渲染的工程圖。每條線由4個坐標值表示:[x_min, y_min, x_max, y_max]
,加上視圖信息和線條類型。
數據預處理示例
在?中,可以看到輸入序列的準備過程:
原始線條數據經過以下處理:
- 坐標量化: 浮點坐標被轉換為離散token
- 視圖分類: 每條線標記屬于哪個視圖(0=正視圖,1=俯視圖,2=側視圖)
- 類型標識: 標記線條類型(可見線/隱藏線)
具體的數據格式示例
處理后的輸入數據格式如下:
數據加載和使用
在訓練器中,這些數據通過?trainer_complete.py:37-38?的LineDataset加載,然后送入模型進行處理。
每個token代表一個坐標分量,4個連續的token組成一條完整的2D線條。通過多模態embedding,這些離散的索引被轉換為512維向量表示,供transformer模型處理。
Notes??注釋
這種格式設計使得模型能夠同時理解幾何坐標、空間位置、視圖信息和線條屬性,為從2D工程圖重建3D結構提供了豐富的輸入表示。
您詢問的是PlankAssembly系統中什么時候需要添加填充掩碼(padding mask)。
填充掩碼的添加時機
在PlankAssembly系統中,填充掩碼在以下幾個關鍵時刻被添加:
1. 數據預處理階段
在LineDataset
和SidefaceDataset
的數據預處理過程中,當序列長度不足最大長度時需要添加填充:?line_data.py:67-72?sideface_data.py:173-177
這里在添加PAD token后立即生成對應的掩碼。
2. 輸出序列準備時
在準備輸出序列時也需要添加填充掩碼:?line_data.py:94-95?sideface_data.py:198-199
3. Transformer模型推理時
在模型的前向傳播過程中,填充掩碼被傳遞給transformer的encoder和decoder:?models.py:206?models.py:212-214
4. 特殊情況檢測
在SidefaceTrainer中,填充掩碼用于檢測是否有有效數據:?trainer_sideface.py:61-65
添加填充掩碼的原因
- 批處理需求: 不同樣本的序列長度不同,需要填充到統一長度
- Attention機制: 防止模型關注無意義的填充位置
- 計算效率: 避免在填充位置進行不必要的計算
- 數據驗證: 檢測輸入序列的有效性
Notes
填充掩碼是在序列被填充到固定長度時自動生成的,這是transformer模型處理變長序列的標準做法。在PlankAssembly中,每當有PAD token被添加時,就需要相應的掩碼來標識這些位置。
您詢問的是PlankAssembly系統中序列的最大長度限制。
序列長度配置
PlankAssembly系統中的序列長度通過配置文件中的MAX_INPUT_LENGTH
和MAX_OUTPUT_LENGTH
參數控制,不同的訓練模式有不同的最大長度設置:
輸入序列最大長度
- Complete模式: 1200?train_complete.yaml:41
- Visible模式: 1000?train_visible.yaml:41
- Sideface模式: 300?train_sideface.yaml:41
輸出序列最大長度
所有模式的輸出序列最大長度都是128?train_complete.yaml:42
在模型中的使用
這些長度參數在PlankModel初始化時被使用:?models.py:26-27
模型會根據這些參數計算最大輸入和輸出數量:?models.py:32-33
長度差異的原因
不同模式的輸入長度限制反映了數據復雜度的差異:
- Complete模式(1200): 包含可見線和隱藏線,數據最復雜
- Visible模式(1000): 只包含可見線,數據量中等
- Sideface模式(300): 處理側面多邊形,數據最簡單
輸出長度統一為128,因為3D形狀程序的復雜度相對固定,每個木板用6個坐標表示,128長度足以容納大多數裝配結構。
Notes
這些長度限制是在配置文件中硬編碼的,可以根據具體需求調整。較長的序列會消耗更多GPU內存,特別是在transformer的attention計算中,內存使用與序列長度的平方成正比。
您詢問的是PlankAssembly系統中輸出序列長度128能容納多少個3D結構(木板)。
輸出序列長度與結構數量的關系
在PlankAssembly系統中,輸出序列的最大長度設置為128?train_complete.yaml:42?。
由于每個木板(plank)用6個坐標值表示邊界框?[x_min, y_min, z_min, x_max, y_max, z_max]
?models.py:24-25?,我們可以計算最大木板數量:
128 ÷ 6 = 21.33,即最多可以容納21個完整的木板結構
模型中的計算邏輯
在PlankModel的初始化中,系統會根據輸出長度和坐標維度計算最大輸出數量:?models.py:32-33
這里max_num_output = math.ceil(max_output_length / num_output_dof)
,即?math.ceil(128 / 6) = 22
個木板位置。
實際使用中的考慮
在訓練過程中,系統會驗證預測輸出的有效性,過濾掉無效的邊界框:
然后將結果重塑為6維邊界框格式:
結論
128長度的輸出序列最多可以表示21-22個木板結構,這個設計足以容納大多數實際的3D裝配場景,因為典型的木制家具或結構通常不會超過20個主要組件。
Notes
這個限制是在配置文件中設定的,可以根據具體需求調整。更長的序列會消耗更多GPU內存,特別是在transformer的attention計算中。
您詢問的是PlankAssembly系統中embedding處理后輸出的數據格式。
Answer
在PlankAssembly系統中,embedding處理后輸出的是高維向量表示,具體維度為num_model
(默認512維)。
Input Embedding輸出
_embed_input
方法將多種輸入特征組合成統一的embedding表示:?models.py:103-112
該方法將所有輸入特征(value、position、coordinate、view、type)的embedding相加,輸出形狀為(batch_size, sequence_length, num_model)
的張量。
Output Embedding輸出
_embed_output
方法處理輸出序列的embedding:?models.py:114-138
輸出embedding同樣是512維向量,包含:
- 值embedding:量化后的坐標值
- 坐標embedding:表示當前處理的是x/y/z坐標還是長寬高
- 位置embedding:表示當前處理的是第幾個3D邊界框
Transformer處理后的數據
經過encoder處理后,embedding數據被轉換為memory表示:?models.py:206
經過decoder處理后,得到hidden states:?models.py:212-214
這些hidden states隨后被用于生成最終的預測分布。
最終輸出數據
在訓練階段,embedding最終轉換為概率分布用于損失計算:?models.py:217-221
在推理階段,通過自回歸采樣生成3D邊界框序列:?models.py:309-315
Notes
embedding的核心作用是將離散的輸入token轉換為連續的向量表示,使transformer能夠處理和學習2D線條圖到3D邊界框的映射關系。所有embedding都是512維向量,這是模型的隱藏維度大小。
您詢問的是如果PlankAssembly系統中沒有embedding會發生什么。
Answer
如果PlankAssembly系統中沒有embedding層,模型將無法正常工作,因為transformer架構完全依賴于embedding來處理輸入數據。
Embedding的必要性
在PlankModel
中,embedding是數據處理的第一步。?models.py:47-53
沒有embedding層,系統將面臨以下問題:
1. 無法處理離散輸入
原始輸入是離散的token ID(量化后的坐標值、位置索引等),transformer需要連續的向量表示才能進行計算。?models.py:103-112
2. 失去位置和語義信息
embedding不僅轉換數據格式,還編碼了重要的語義信息:
- 坐標維度信息(x/y/z坐標vs長寬高)
- 視圖類型信息(前視圖/頂視圖/側視圖)
- 序列位置信息
3. Transformer無法運行
Encoder和decoder都期望接收embedding后的向量作為輸入。?models.py:279
沒有embedding,這些組件將無法處理原始的整數token。
4. 訓練過程中斷
訓練步驟依賴于模型的正常前向傳播。?trainer_complete.py:63-71
沒有embedding,模型無法產生有效的loss和accuracy指標。
Notes
Embedding在PlankAssembly中不是可選組件,而是核心架構的基礎部分。它將離散的2D線條圖特征轉換為transformer可以處理的連續向量空間,使得從2D到3D的映射學習成為可能。移除embedding等同于破壞了整個模型架構。