Ручная обрезка (принудительная обрезка) участков в Matplotlib - PullRequest
0 голосов
/ 21 октября 2018

Я пытаюсь придумать программный способ создания визуалов для сверточных нейронных сетей (CNN).Нечто похожее на это:

Для этого нужно много поиграться с Axes3D и SubPlots.

Предположим, у меня есть случайное сгенерированное входное изображение размером 128x128.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
import matplotlib.pyplot as plt

data = np.random.randint(255,size=(128,128))

Затем я пытаюсьподготовьте график, чтобы эти данные были «поданы» в CNN.Я создаю фигуру и настраиваю расположение подзаговоров, используя GridSpec.

fig = plt.figure(figsize=(6,3))
gs = gridspec.GridSpec(nrows=1, ncols=2) # no spacing between subplots
gs.update(wspace=0, hspace=0)

Вот первый подзаговор:

## INPUT IMAGE

ax = plt.subplot(gs[0], projection='3d')
xx, yy = np.meshgrid(np.linspace(-1,1,data.shape[0]), np.linspace(1,-1,data.shape[1]))
X = 0 * xx
Y = xx
Z = yy
ax.set_facecolor('#AAAAFF')
# ax.set_axis_off()
ax.plot_surface(X, Y, Z, rstride=10, cstride=10, facecolors=plt.cm.Greys_r(data), shade=False)
ax.view_init(20, -60) # adjust rotation
ax.set_xlim(np.array([-0.8,0.8]))
ax.set_ylim(np.array([-0.8,0.8]))
ax.set_zlim(np.array([-0.8,0.8]))
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.set_zticklabels([])

Затем второй подзаговор:

## CONV LAYER 1

ax = plt.subplot(gs[1], projection='3d')
ax.set_facecolor('#AAFFAA')
# ax.set_axis_off()
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.set_zticklabels([])
ax.view_init(20, -60) # adjust rotation
ax.set_ylim(np.array([-0.8,0.8]))
ax.set_ylim(np.array([-0.8,0.8]))
ax.set_zlim(np.array([-0.8,0.8]))

num_channels = 64; channels = np.linspace(-1, 1, int(np.sqrt(num_channels)))
layer_size = 1

# vertices for each "channel" of the CNN layer
v = np.array([
    [a,b,c] for a in channels for b in [-layer_size/2, layer_size/2] for c in [-layer_size/2, layer_size/2]
])

for k in range(int(np.sqrt(num_channels))):
    verts = [[v[x] for x in [4*k+0,4*k+1,4*k+3,4*k+2]] ]
    face = Poly3DCollection(verts, linewidths=1, edgecolors='w')
    #face.set_alpha(1/(k+1))
    face.set_facecolor('#ff99cc')
    ax.add_collection3d(face)

И наконец, я излагаю результаты:

plt.show()

И затем я получаю это:

Я проиллюстрировал мою проблему, используя голубоватый и зеленоватый фон и показывая Оси.Мне бы очень хотелось уменьшить пространство, занимаемое этими 3D-графиками, чтобы оно могло выглядеть примерно так:

Кто-нибудь знает, возможно ли это?Как мне обрезать участки, чтобы получить как можно меньше отступов?Возможно ли даже иметь участки с неравной шириной в Matplotlib?

Заранее спасибо всем, кто попытается это сделать.

...