mirror of
https://github.com/unanmed/ginka-generator.git
synced 2026-05-16 14:31:11 +08:00
chore: 调整数据集
This commit is contained in:
parent
10166fa073
commit
df2bd80bec
@ -103,7 +103,14 @@ const ignoredTower: string[] = [
|
||||
'zjhy1',
|
||||
'zrsz',
|
||||
'zuozuozhieX_renewed',
|
||||
'ZZZE50Ex'
|
||||
'ZZZE50Ex',
|
||||
'1DQSJ',
|
||||
'againstcov',
|
||||
'Alive',
|
||||
'Aria',
|
||||
'atom',
|
||||
'bdf1',
|
||||
'bingyuanhouzhuan'
|
||||
];
|
||||
|
||||
const ignoredFloor: Record<string, string[]> = {
|
||||
@ -119,7 +126,8 @@ const ignoredFloor: Record<string, string[]> = {
|
||||
'MT71',
|
||||
'ML26',
|
||||
'ML27',
|
||||
'MQ28'
|
||||
'MQ28',
|
||||
'MT104'
|
||||
],
|
||||
cxzl: [
|
||||
'MT63',
|
||||
@ -153,11 +161,11 @@ const ignoredFloor: Record<string, string[]> = {
|
||||
zd1: ['MH9', 'MT10'],
|
||||
zhenshishenghuo: ['MT52', 'MT131', 'MT132'],
|
||||
CatLegend: ['MT20', 'MT63', 'MT67'],
|
||||
cxzl_wycx: ['MT304', 'MT777'],
|
||||
cxzl_wycx: ['MT304', 'MT777', 'MT494'],
|
||||
evernight: ['MT30'],
|
||||
bits1: ['MT28'],
|
||||
bits2: ['dltsd5'],
|
||||
bits114514: ['bysl7', 'byxd3', 'mkpy6', 'sdhxmiddle1'],
|
||||
bits2: ['dltsd5', 'hdxd5'],
|
||||
bits114514: ['bysl7', 'byxd3', 'mkpy6', 'sdhxmiddle1', 'zlzl1', 'zlzl2'],
|
||||
Black: ['MT12'],
|
||||
chaoshuang2: ['MT153'],
|
||||
EasyPreduct: ['PT40'],
|
||||
@ -214,10 +222,36 @@ const ignoredFloor: Record<string, string[]> = {
|
||||
WhiteLily_1521: ['B9'],
|
||||
xsdsj: ['MT40'],
|
||||
xxchuanshuo0: ['D35', 'D38', 'D39'],
|
||||
yesterdayReturn: ['MT6-1']
|
||||
yesterdayReturn: ['MT6-1'],
|
||||
'9922': [
|
||||
'Ch4_15',
|
||||
'East3',
|
||||
'East7',
|
||||
'MT12',
|
||||
'East11',
|
||||
'North2',
|
||||
'North3',
|
||||
'North4'
|
||||
],
|
||||
amiyamiya: ['MT27']
|
||||
};
|
||||
|
||||
const labelConfig: IAutoLabelConfig = {
|
||||
classes: {
|
||||
empty: 0,
|
||||
wall: 1,
|
||||
decoration: 2,
|
||||
commonDoors: [3],
|
||||
specialDoors: [6, 6],
|
||||
keys: [7],
|
||||
redGems: [10],
|
||||
blueGems: [13],
|
||||
greenGems: [16],
|
||||
potions: [19],
|
||||
items: [23],
|
||||
enemies: [26],
|
||||
entry: 29
|
||||
},
|
||||
allowedSize: [[13, 13]],
|
||||
allowUselessBranch: false,
|
||||
maxWallDensityStd: 0.25,
|
||||
@ -228,19 +262,25 @@ const labelConfig: IAutoLabelConfig = {
|
||||
minResourceRatio: 0.02,
|
||||
maxResourceRatio: 0.3,
|
||||
minDoorRatio: 0,
|
||||
maxDoorRatio: 0.2,
|
||||
maxDoorRatio: 0.12,
|
||||
minFishCount: 0,
|
||||
maxFishCount: 2,
|
||||
minEntryCount: 1,
|
||||
maxEntryCount: 4,
|
||||
ignoreIssues: true,
|
||||
customTowerFilter: info => {
|
||||
// if (info.name !== 'Apeiria') {
|
||||
// return false;
|
||||
// }
|
||||
// if (info.color !== TowerColor.Blue && info.color !== TowerColor.Green) {
|
||||
// return false;
|
||||
// }
|
||||
if (info.people < 1000) {
|
||||
return false;
|
||||
}
|
||||
if (info.name.startsWith('50') && info.name.length > 2) {
|
||||
return false;
|
||||
}
|
||||
if (info.name.startsWith('51') && info.name.length > 2) {
|
||||
return false;
|
||||
}
|
||||
@ -250,7 +290,6 @@ const labelConfig: IAutoLabelConfig = {
|
||||
if (ignoredTower.includes(info.name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
customFloorFilter: floor => {
|
||||
@ -267,7 +306,7 @@ const labelConfig: IAutoLabelConfig = {
|
||||
return false;
|
||||
}
|
||||
if (floor.tower.name === 'Apeiria') {
|
||||
return Math.random() > 0.9;
|
||||
return Math.random() < 0.2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ export async function autoLabelTowers(
|
||||
continue;
|
||||
}
|
||||
// 转换楼层
|
||||
const converted = convertTowerMap(result, floor);
|
||||
const converted = convertTowerMap(result, floor, config);
|
||||
const floorInfo = parseFloorInfo(info, converted.map);
|
||||
const floorData: IConvertedMapInfo = {
|
||||
data: converted,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { readFile } from 'fs/promises';
|
||||
import { IFloorInfo, ITowerInfo, TowerColor } from './types';
|
||||
import { buildTopologicalGraph } from 'src/topology/graph';
|
||||
import { buildTopologicalGraph } from '../topology/graph';
|
||||
import {
|
||||
commonDoorTiles,
|
||||
doorTiles,
|
||||
@ -14,8 +14,8 @@ import {
|
||||
resourceTiles,
|
||||
specialDoorTiles,
|
||||
wallTiles
|
||||
} from 'src/shared';
|
||||
import { NodeType } from 'src/topology/interface';
|
||||
} from '../shared';
|
||||
import { NodeType } from '../topology/interface';
|
||||
|
||||
interface IRawTowerInfo {
|
||||
/** 作者 id */
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
import { ICodeRunResult, IConvertedMap, INeededFloorData } from './types';
|
||||
import {
|
||||
IAutoLabelConfig,
|
||||
ICodeRunResult,
|
||||
IConvertedMap,
|
||||
INeededFloorData
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* 运行塔的代码
|
||||
@ -39,7 +44,8 @@ function edge(x: number, y: number, width: number, height: number) {
|
||||
|
||||
export function convertTowerMap(
|
||||
result: ICodeRunResult,
|
||||
floor: INeededFloorData
|
||||
floor: INeededFloorData,
|
||||
config: IAutoLabelConfig
|
||||
): IConvertedMap {
|
||||
const width = floor.map[0].length;
|
||||
const height = floor.map.length;
|
||||
@ -109,33 +115,31 @@ export function convertTowerMap(
|
||||
core.status.hero.def = 0;
|
||||
core.status.hero.mdef = 0;
|
||||
|
||||
const tiles = config.classes;
|
||||
|
||||
for (let nx = 0; nx < width; nx++) {
|
||||
for (let ny = 0; ny < height; ny++) {
|
||||
const num = floor.map[ny][nx];
|
||||
if (num === 0) {
|
||||
converted[ny][nx] = 0;
|
||||
continue;
|
||||
} else if (num === 17) {
|
||||
hasCannotInOut = true;
|
||||
converted[ny][nx] = 0;
|
||||
if (num === 0 || num === 17) {
|
||||
converted[ny][nx] = tiles.empty;
|
||||
continue;
|
||||
}
|
||||
const loc = `${nx},${ny}`;
|
||||
if (floor.changeFloor[loc]) {
|
||||
converted[ny][nx] = 29;
|
||||
converted[ny][nx] = tiles.entry;
|
||||
continue;
|
||||
}
|
||||
const block = result.map[num];
|
||||
if (!block) {
|
||||
// 图块不存在说明是额外素材中的内容,默认不可通行,视为墙壁
|
||||
converted[ny][nx] = 1;
|
||||
converted[ny][nx] = tiles.wall;
|
||||
continue;
|
||||
}
|
||||
// 怪物处理
|
||||
if (block.cls === 'enemys' || block.cls === 'enemy48') {
|
||||
const enemy = result.enemy[block.id];
|
||||
if (!enemy) {
|
||||
converted[ny][nx] = 0;
|
||||
converted[ny][nx] = tiles.empty;
|
||||
continue;
|
||||
}
|
||||
const value = enemy.hp * (enemy.atk + enemy.def);
|
||||
@ -146,7 +150,7 @@ export function convertTowerMap(
|
||||
if (block.cls === 'items') {
|
||||
const item = result.item[block.id];
|
||||
if (!item) {
|
||||
converted[ny][nx] = 0;
|
||||
converted[ny][nx] = tiles.empty;
|
||||
continue;
|
||||
}
|
||||
// 先清空内容
|
||||
@ -155,22 +159,32 @@ export function convertTowerMap(
|
||||
heroStatus.def = 0;
|
||||
heroStatus.mdef = 0;
|
||||
if (block.id === 'pickaxe') {
|
||||
converted[ny][nx] = 24;
|
||||
const idx = Math.min(tiles.items.length - 1, 0);
|
||||
converted[ny][nx] = tiles.items[idx];
|
||||
continue;
|
||||
} else if (block.id === 'bomb') {
|
||||
converted[ny][nx] = 24;
|
||||
const idx = Math.min(tiles.items.length - 1, 1);
|
||||
converted[ny][nx] = tiles.items[idx];
|
||||
continue;
|
||||
} else if (block.id === 'centerFly') {
|
||||
converted[ny][nx] = 23;
|
||||
const idx = Math.min(tiles.items.length - 1, 2);
|
||||
converted[ny][nx] = tiles.items[idx];
|
||||
continue;
|
||||
} else if (block.id === 'yellowKey') {
|
||||
converted[ny][nx] = 7;
|
||||
const idx = Math.min(tiles.items.length - 1, 0);
|
||||
converted[ny][nx] = tiles.keys[idx];
|
||||
continue;
|
||||
} else if (block.id === 'blueKey') {
|
||||
converted[ny][nx] = 8;
|
||||
const idx = Math.min(tiles.items.length - 1, 1);
|
||||
converted[ny][nx] = tiles.keys[idx];
|
||||
continue;
|
||||
} else if (block.id === 'redKey') {
|
||||
converted[ny][nx] = 9;
|
||||
const idx = Math.min(tiles.items.length - 1, 2);
|
||||
converted[ny][nx] = tiles.keys[idx];
|
||||
continue;
|
||||
} else if (block.id === 'greenKey') {
|
||||
const idx = Math.min(tiles.items.length - 1, 3);
|
||||
converted[ny][nx] = tiles.keys[idx];
|
||||
continue;
|
||||
}
|
||||
// 执行道具效果
|
||||
@ -213,30 +227,34 @@ export function convertTowerMap(
|
||||
itemMap.set(ny * width + nx, arr);
|
||||
continue;
|
||||
} else {
|
||||
converted[ny][nx] = 0;
|
||||
converted[ny][nx] = tiles.empty;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// 门信息,这种处理方式只能处理 2.7+ 的塔,老塔估计处理不了,不过老塔占比也不大,忽略就好了
|
||||
if (block.doorInfo && Object.keys(block.doorInfo.keys).length > 0) {
|
||||
if (block.id === 'specialDoor') {
|
||||
converted[ny][nx] = 6;
|
||||
converted[ny][nx] = tiles.specialDoors[0];
|
||||
continue;
|
||||
} else if (
|
||||
'redKey' in block.doorInfo.keys ||
|
||||
'greenKey' in block.doorInfo.keys
|
||||
) {
|
||||
converted[ny][nx] = 5;
|
||||
} else if ('greenKey' in block.doorInfo.keys) {
|
||||
const idx = Math.min(tiles.commonDoors.length - 1, 3);
|
||||
converted[ny][nx] = tiles.commonDoors[idx];
|
||||
} else if ('redKey' in block.doorInfo.keys) {
|
||||
const idx = Math.min(tiles.commonDoors.length - 1, 2);
|
||||
converted[ny][nx] = tiles.commonDoors[idx];
|
||||
continue;
|
||||
} else if ('blueKey' in block.doorInfo.keys) {
|
||||
converted[ny][nx] = 4;
|
||||
const idx = Math.min(tiles.commonDoors.length - 1, 1);
|
||||
converted[ny][nx] = tiles.commonDoors[idx];
|
||||
continue;
|
||||
} else if ('yellowKey' in block.doorInfo.keys) {
|
||||
converted[ny][nx] = 3;
|
||||
const idx = Math.min(tiles.commonDoors.length - 1, 0);
|
||||
converted[ny][nx] = tiles.commonDoors[idx];
|
||||
continue;
|
||||
} else {
|
||||
// 其他门一律视为黄门
|
||||
converted[ny][nx] = 3;
|
||||
// 其余视为绿门
|
||||
const idx = Math.min(tiles.commonDoors.length - 1, 3);
|
||||
converted[ny][nx] = tiles.commonDoors[idx];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -261,16 +279,16 @@ export function convertTowerMap(
|
||||
fg2Block?.cannotIn ||
|
||||
fg2Block?.cannotOut
|
||||
) {
|
||||
converted[ny][nx] = 0;
|
||||
converted[ny][nx] = tiles.empty;
|
||||
hasCannotInOut = true;
|
||||
continue;
|
||||
}
|
||||
// 墙壁处理
|
||||
if (block.canPass) {
|
||||
converted[ny][nx] = 0;
|
||||
converted[ny][nx] = tiles.empty;
|
||||
continue;
|
||||
} else {
|
||||
converted[ny][nx] = 1;
|
||||
converted[ny][nx] = tiles.wall;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -285,15 +303,18 @@ export function convertTowerMap(
|
||||
enemyMap.forEach((value, pos) => {
|
||||
const nx = pos % width;
|
||||
const ny = Math.floor(pos / width);
|
||||
converted[ny][nx] = 26;
|
||||
converted[ny][nx] = tiles.enemies[0];
|
||||
});
|
||||
} else {
|
||||
enemyMap.forEach((value, pos) => {
|
||||
const nx = pos % width;
|
||||
const ny = Math.floor(pos / width);
|
||||
const ratio = (value - minEnemyValue) / enemyValueDelta;
|
||||
const n = Math.min(Math.floor(ratio * 3), 2);
|
||||
converted[ny][nx] = 26 + n;
|
||||
const idx = Math.min(
|
||||
Math.floor(ratio * tiles.enemies.length),
|
||||
tiles.enemies.length - 1
|
||||
);
|
||||
converted[ny][nx] = tiles.enemies[idx];
|
||||
});
|
||||
}
|
||||
|
||||
@ -317,19 +338,19 @@ export function convertTowerMap(
|
||||
// 资源判定为占比最大的那个
|
||||
// 如果只有一种资源且道具包含这种属性,全部使用最低的资源种类
|
||||
if (minHpValue === maxHpValue && hp > 0) {
|
||||
converted[ny][nx] = 19;
|
||||
converted[ny][nx] = tiles.potions[0];
|
||||
return;
|
||||
}
|
||||
if (minAtkValue === maxAtkValue && atk > 0) {
|
||||
converted[ny][nx] = 10;
|
||||
converted[ny][nx] = tiles.redGems[0];
|
||||
return;
|
||||
}
|
||||
if (minDefValue === maxDefValue && def > 0) {
|
||||
converted[ny][nx] = 13;
|
||||
converted[ny][nx] = tiles.blueGems[0];
|
||||
return;
|
||||
}
|
||||
if (minMdefValue === maxMdefValue && mdef > 0) {
|
||||
converted[ny][nx] = 16;
|
||||
converted[ny][nx] = tiles.greenGems[0];
|
||||
return;
|
||||
}
|
||||
const hpRatio = (hp - minHpValue) / hpValueDelta;
|
||||
@ -353,68 +374,38 @@ export function convertTowerMap(
|
||||
switch (maxIndex) {
|
||||
case 0: {
|
||||
// 血瓶
|
||||
const n = Math.min(Math.floor(hpRatio * 4), 3);
|
||||
converted[ny][nx] = 19 + n;
|
||||
const idx = Math.min(
|
||||
Math.floor(hpRatio * tiles.potions.length),
|
||||
tiles.potions.length - 1
|
||||
);
|
||||
converted[ny][nx] = tiles.potions[idx];
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
// 红宝石,这里不可能只有一种数值了,不需要判断
|
||||
if (itemAtkSet.size === 2) {
|
||||
if (atkRatio <= 0.5) {
|
||||
// 小宝石
|
||||
converted[ny][nx] = 10;
|
||||
} else {
|
||||
// 大宝石
|
||||
if (maxAtkValue / minAtkValue > 3) {
|
||||
converted[nx][nx] = 12;
|
||||
} else {
|
||||
converted[ny][nx] = 11;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const n = Math.min(Math.floor(atkRatio * 3), 2);
|
||||
converted[ny][nx] = 10 + n;
|
||||
}
|
||||
const idx = Math.min(
|
||||
Math.floor(atkRatio * tiles.redGems.length),
|
||||
tiles.redGems.length - 1
|
||||
);
|
||||
converted[ny][nx] = tiles.redGems[idx];
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// 蓝宝石,这里不可能只有一种数值了,不需要判断
|
||||
if (itemDefSet.size === 2) {
|
||||
if (defRatio <= 0.5) {
|
||||
// 小宝石
|
||||
converted[ny][nx] = 13;
|
||||
} else {
|
||||
// 大宝石
|
||||
if (maxDefValue / minDefValue > 3) {
|
||||
converted[nx][nx] = 15;
|
||||
} else {
|
||||
converted[ny][nx] = 14;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const n = Math.min(Math.floor(defRatio * 3), 2);
|
||||
converted[ny][nx] = 13 + n;
|
||||
}
|
||||
const idx = Math.min(
|
||||
Math.floor(defRatio * tiles.blueGems.length),
|
||||
tiles.blueGems.length - 1
|
||||
);
|
||||
converted[ny][nx] = tiles.blueGems[idx];
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// 绿宝石,这里不可能只有一种数值了,不需要判断
|
||||
if (itemMdefSet.size === 2) {
|
||||
if (mdefRatio <= 0.5) {
|
||||
// 小宝石
|
||||
converted[ny][nx] = 16;
|
||||
} else {
|
||||
// 大宝石
|
||||
if (maxMdefValue / minMdefValue > 3) {
|
||||
converted[nx][nx] = 18;
|
||||
} else {
|
||||
converted[ny][nx] = 17;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const n = Math.min(Math.floor(mdefRatio * 3), 2);
|
||||
converted[ny][nx] = 16 + n;
|
||||
}
|
||||
const idx = Math.min(
|
||||
Math.floor(mdefRatio * tiles.greenGems.length),
|
||||
tiles.greenGems.length - 1
|
||||
);
|
||||
converted[ny][nx] = tiles.greenGems[idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -428,7 +419,7 @@ export function convertTowerMap(
|
||||
!isFinite(converted[ny][nx]) ||
|
||||
converted[ny][nx] < 0
|
||||
) {
|
||||
converted[ny][nx] = 0;
|
||||
converted[ny][nx] = tiles.empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +95,44 @@ export interface IFloorInfo {
|
||||
readonly wallDensityStd: number;
|
||||
}
|
||||
|
||||
export interface IMapBlockConfig {
|
||||
/** 空地的图块数字 */
|
||||
readonly empty: number;
|
||||
/** 墙的图块数字 */
|
||||
readonly wall: number;
|
||||
/** 装饰图块 */
|
||||
readonly decoration: number;
|
||||
/**
|
||||
* 普通门,黄、蓝、红、绿等级依次增加,如果数组长度不够,会取最高级的那个,
|
||||
* 对于四种基础门之外的门,会进入 `specialDoors` 判断
|
||||
*/
|
||||
readonly commonDoors: number[];
|
||||
/** 机关门,普通机关门使用第一项作为结果,对于四种基础门及机关门之外的门,会选用第二项作为结果 */
|
||||
readonly specialDoors: [number, number];
|
||||
/**
|
||||
* 钥匙,黄、蓝、红、绿等级依次增加,如果数组长度不够,会取最高级的那个,
|
||||
* 特殊钥匙视为最高级
|
||||
*/
|
||||
readonly keys: number[];
|
||||
/** 红宝石图块,平均分为若干档 */
|
||||
readonly redGems: number[];
|
||||
/** 蓝宝石图块,平均分为若干档 */
|
||||
readonly blueGems: number[];
|
||||
/** 绿宝石图块,平均分为若干档 */
|
||||
readonly greenGems: number[];
|
||||
/** 血瓶图块,平均分为若干档 */
|
||||
readonly potions: number[];
|
||||
/** 道具图块,依次为破炸飞,如果长度不够则取最后一个 */
|
||||
readonly items: number[];
|
||||
/** 怪物图块,按怪物强度分为若干当,强度为血量乘攻防和 */
|
||||
readonly enemies: number[];
|
||||
/** 入口图块 */
|
||||
readonly entry: number;
|
||||
}
|
||||
|
||||
export interface IAutoLabelConfig {
|
||||
/** 地图图块分类 */
|
||||
readonly classes: Readonly<IMapBlockConfig>;
|
||||
/** 地图允许大小 */
|
||||
readonly allowedSize: [number, number][];
|
||||
/** 是否允许无用节点 */
|
||||
|
||||
@ -2,15 +2,15 @@
|
||||
export const emptyTiles = new Set([0]);
|
||||
export const wallTiles = new Set([1]);
|
||||
export const decorationTiles = new Set([2]);
|
||||
export const commonDoorTiles = new Set([3, 4, 5]);
|
||||
export const commonDoorTiles = new Set([3]);
|
||||
export const specialDoorTiles = new Set([6]);
|
||||
export const keyTiles = new Set([7, 8, 9]);
|
||||
export const redGemTiles = new Set([10, 11, 12]);
|
||||
export const blueGemTiles = new Set([13, 14, 15]);
|
||||
export const greenGemTiles = new Set([16, 17, 18]);
|
||||
export const potionTiles = new Set([19, 20, 21, 22]);
|
||||
export const itemTiles = new Set([23, 24, 25]);
|
||||
export const enemyTiles = new Set([26, 27, 28]);
|
||||
export const keyTiles = new Set([7]);
|
||||
export const redGemTiles = new Set([10]);
|
||||
export const blueGemTiles = new Set([13]);
|
||||
export const greenGemTiles = new Set([16]);
|
||||
export const potionTiles = new Set([19]);
|
||||
export const itemTiles = new Set([23]);
|
||||
export const enemyTiles = new Set([26]);
|
||||
export const entryTiles = new Set([29]);
|
||||
|
||||
// 组合图块定义
|
||||
|
||||
@ -67,13 +67,18 @@ class EncoderFusion(nn.Module):
|
||||
num_layers=2
|
||||
)
|
||||
self.norm = nn.LayerNorm(d_model)
|
||||
self.fc = nn.Sequential(
|
||||
nn.Linear(d_model * 2, d_model * 2),
|
||||
nn.LayerNorm(d_model * 2),
|
||||
nn.GELU()
|
||||
)
|
||||
|
||||
def forward(self, logits):
|
||||
x = self.norm(self.transformer(logits))
|
||||
h_mean = torch.mean(x, dim=1)
|
||||
h_max = torch.max(x, dim=1).values
|
||||
h = torch.cat([h_mean, h_max], dim=1)
|
||||
return h
|
||||
return self.fc(h)
|
||||
|
||||
class VAEEncoder(nn.Module):
|
||||
def __init__(self, device, tile_classes=32, latent_dim=32, width=13, height=13):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user