推荐收藏!万字长文带入快速使用 keras

这些年,有很多感悟:一个人精力是有限的,一个人视野也有有限的,你总会不经意间发现优秀人的就在身边。

看我文章的小伙伴应该经常听我说过的一句话:技术要学会交流、分享,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。 这句话是这些年经验的总结。

本文就是由我们粉丝群的小伙伴讨论、分享的总结,最终汇总成了这个《keras 快速使用手册》,如果你也喜欢学习、交流,可以文末的方式加入我们。

我们开始正题:

keras快速使用手册

import keras
import tensorflow as tf
print(keras.__version__)
print(tf.__version__)

基本命令

import random
import tensorflow as tf
import numpy as np
import os
def seed_everything(seed):random.seed(seed)os.environ['PYTHONHASHSEED'] = str(seed)np.random.seed(seed)tf.random.set_seed(seed)seed_everything(2019)

定义数据的输入和输出

直接加载到内存中

train_x = np.random.radnom((1000,23))
train_y = np.random.radnom((1000,1))
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(train_x, train_y, test_size=0.1, random_state=0, shuffle=True)

迭代器的形式读取数据

import keras# helper function for data visualization    
def denormalize(x):"""Scale image to range 0..1 for correct plot"""x_max = np.percentile(x, 98)x_min = np.percentile(x, 2)    x = (x - x_min) / (x_max - x_min)x = x.clip(0, 1)return x# classes for data loading and preprocessing
class Dataset:"""CamVid Dataset. Read images, apply augmentation and preprocessing transformations.Args:images_dir (str): path to images foldermasks_dir (str): path to segmentation masks folderclass_values (list): values of classes to extract from segmentation maskaugmentation (albumentations.Compose): data transfromation pipeline (e.g. flip, scale, etc.)preprocessing (albumentations.Compose): data preprocessing (e.g. noralization, shape manipulation, etc.)"""def __init__(self, images_dir, masks_dir, classes=None, augmentation=None, preprocessing=None,):self.CLASSES = ['sky', 'building', 'pole', 'road', 'pavement', 'tree', 'signsymbol', 'fence', 'car', 'pedestrian', 'bicyclist', 'unlabelled']self.ids = os.listdir(images_dir)self.images_fps = [os.path.join(images_dir, image_id) for image_id in self.ids]self.masks_fps = [os.path.join(masks_dir, image_id) for image_id in self.ids]# convert str names to class values on masksself.class_values = [self.CLASSES.index(cls.lower()) for cls in self.CLASSES]self.augmentation = augmentationself.preprocessing = preprocessingdef __getitem__(self, i):# read dataimage = cv2.imread(self.images_fps[i])image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)image = cv2.resize(image,(480,480))mask = cv2.imread(self.masks_fps[i], 0)mask = cv2.resize(mask,(480,480))# extract certain classes from mask (e.g. cars)masks = [(mask == v) for v in self.class_values]mask = np.stack(masks, axis=-1).astype('float')# add background if mask is not binaryif mask.shape[-1] != 1:background = 1 - mask.sum(axis=-1, keepdims=True)mask = np.concatenate((mask, background), axis=-1)# apply augmentationsif self.augmentation:sample = self.augmentation(image=image, mask=mask)image, mask = sample['image'], sample['mask']# apply preprocessingif self.preprocessing:sample = self.preprocessing(image=image, mask=mask)image, mask = sample['image'], sample['mask']return image, maskdef __len__(self):return len(self.ids)class Dataloder(keras.utils.Sequence):"""Load data from dataset and form batchesArgs:dataset: instance of Dataset class for image loading and preprocessing.batch_size: Integet number of images in batch.shuffle: Boolean, if `True` shuffle image indexes each epoch."""def __init__(self, dataset, batch_size=1, augment=None, shuffle=False):self.dataset = datasetself.batch_size = batch_sizeself.shuffle = shuffleself.indexes = np.arange(len(dataset))self.augment = augmentself.on_epoch_end()def __getitem__(self, i):# collect batch datastart = i * self.batch_sizestop = (i + 1) * self.batch_sizedata = []for j in range(start, stop):if self.augment is None:data.append(np.array(X),np.array(y))else:            im,mask = [],[]   for x,y in zip(X,y):augmented = self.augment(image=x, mask=y)im.append(augmented['image'])mask.append(augmented['mask'])data.append(np.array(im),np.array(mask))# transpose list of listsbatch = [np.stack(samples, axis=0) for samples in zip(*data)]return batchdef __len__(self):"""Denotes the number of batches per epoch"""return len(self.indexes) // self.batch_sizedef on_epoch_end(self):"""Callback function to shuffle indexes each epoch"""if self.shuffle:self.indexes = np.random.permutation(self.indexes)  # Dataset for validation images
train_dataset = Dataset(x_train_dir, y_train_dir)
valid_dataset = Dataset(x_valid_dir, y_valid_dir)# check shapes for errors
BATCH_SIZE =4
train_dataloader = Dataloder(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
valid_dataloader = Dataloder(valid_dataset, batch_size=BATCH_SIZE, shuffle=False)

数据增强

from albumentations import (Compose, HorizontalFlip, CLAHE, HueSaturationValue,RandomBrightness, RandomContrast, RandomGamma, OneOf,ToFloat, ShiftScaleRotate, GridDistortion, ElasticTransform, JpegCompression, HueSaturationValue,RGBShift, RandomBrightness, RandomContrast, Blur, MotionBlur, MedianBlur, GaussNoise, CenterCrop,IAAAdditiveGaussianNoise, GaussNoise, OpticalDistortion, RandomSizedCrop
)AUGMENTATIONS_TRAIN = Compose([HorizontalFlip(p=0.5),OneOf([RandomContrast(),RandomGamma(),RandomBrightness(),], p=0.3),OneOf([ElasticTransform(alpha=120, sigma=120 * 0.05, alpha_affine=120 * 0.03),GridDistortion(),OpticalDistortion(distort_limit=2, shift_limit=0.5),], p=0.3),RandomSizedCrop(min_max_height=(sz / 2, sz), height=h, width=w, p=0.5),ToFloat(max_value=1)
], p=1)AUGMENTATIONS_TEST = Compose([ToFloat(max_value=1)
], p=1)train_dataloader = Dataloder(train_dataset, batch_size=BATCH_SIZE,augment=AUGMENTATIONS_TRAIN,shuffle=True)
valid_dataloader = Dataloder(valid_dataset, batch_size=BATCH_SIZE, augment=AUGMENTATIONS_TEST,shuffle=False)

定义网络模型

from keras.layers import *
from keras.models import *
import warnings
warnings.filterwarnings("ignore")def my_model(input_shape, with_dropout= True):m_input = Input(input_shape)out = Conv2D(32, 3,padding='same', activation="relu")(m_input)out = BatchNormalization()(out)out = MaxPool2D(2)(out)out = Conv2D(64, 3, padding='same', activation="relu")(out)out = Conv2D(64, 3, padding='same', activation="relu")(out)out = Conv2D(64, 3, padding='same', activation="relu")(out)out = BatchNormalization()(out)out = MaxPool2D(2)(out)out = Conv2D(64, 3, padding='same', activation="relu")(out)out = Conv2D(64, 3, padding='same', activation="relu")(out)out = Conv2D(64, 3, padding='same', activation="relu")(out)out = BatchNormalization()(out)out = MaxPool2D(2)(out)out = Conv2D(128, 3, padding='same', activation="relu")(out)out = Conv2D(128, 3, padding='same', activation="relu")(out)out = Conv2D(128, 3, padding='same', activation="relu")(out)out = BatchNormalization()(out)out = MaxPool2D(2)(out)out = Conv2D(128, 3, padding='same', activation="relu")(out)out = Conv2D(128, 3, padding='same', activation="relu")(out)out = Conv2D(128, 3, padding='same', activation="relu")(out)out = Flatten()(out)out = Dense(64, activation="relu")(out)if with_dropout:out = Dropout(0.4)(out)out = Dense(2, activation="linear")(out)model = Model(m_input, out)return modelmodel = my_model((128,128,1))
model.summary()

获得网络所有的层

  • 获得每一层模型的名称,是否可训练,权重信息
print(" model layers:",len(model.layers))
x = np.random.random((1,128,128,1))
out = model.predict(x)
print("output size:",x.shape)
for layer in model.layers:print(layer.name,layer.trainable)if len(layer.weights)>0:print(layer.weights[0].shape)break
import keras.backend as K
from keras.layers import  *
import numpy as npmodel=Nonemodel.load_weights("finall_weights.h5")def get_layers_output(model,x_input,index):middle_layer = K.function([model.input], [model.layers[index].output])middle_out=middle_layer([np.expand_dims(x_input,axis=0)])[0]return middle_out############################################################################
##获得某一层的权重
layer_dict = dict([(layer.name, layer) for layer in model.layers])
print(layer_dict)
print(model.layers[-1].output)
last_weights=model.layers[-1].get_weights()[0]
last_bais=model.layers[-1].get_weights()[1]
print("last layer weights:",last_weights.shape)
print("last layer bias:",last_bais,last_bais.shape) ##[0.4908378  0.48844907]############################################################################
##获得某一层的输出
x_train=np.random.random((1,100,100,))
first_layer_out=get_layers_output(model,x_train[0],1)
print(first_layer_out[:,1,1,:3])  ## results:[[0.07100815 0.38357598 0.        ]]
########################################################################################################################################################
##设置模型网络层是否可训练
def make_trainable(net, val):net.trainable = valfor l in net.layers:l.trainable = val
# make_trainable(model,False)
############################################################################

获得网络的权重参数

t=model.get_layer('conv2d_14')
print(t)
for index in t.get_weights():print(index.shape)

冻结网络的某一层

for layer in model.layers:if not isinstance(layer, BatchNormalization):layer.trainable = False

保存和加载权重参数信息

model.save_weights("weights.h5")  ## v1
model.load_weights("weights.h5",by_name=True)## v2def IoU(y_true, y_pred, eps=1e-6):if K.max(y_true) == 0.0:return IoU(1-y_true, 1-y_pred) ## empty image; calc IoU of zerosintersection = K.sum(y_true * y_pred, axis=[1,2,3])union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3]) - intersectionreturn K.mean( (intersection + eps) / (union + eps), axis=0)

加载模型

from keras.models import load_model
model = load_model('model.h5', custom_objects={'IoU': IoU}) ## v3model.save("path_to_my_model")

检查权重是否加载成功

model = get_model()
# Train the model.
test_input = np.random.random((128, 32))
test_target = np.random.random((128, 1))
model.fit(test_input, test_target)# Calling `save('my_model')` creates a SavedModel folder `my_model`.
model.save("my_model")# It can be used to reconstruct the model identically.
reconstructed_model = keras.models.load_model("my_model")
# # Option 1: Load with the custom_object argument.
# reconstructed_model = keras.models.load_model(
#     "my_model", custom_objects={"CustomModel": CustomModel}
# )# Let's check:
np.testing.assert_allclose(model.predict(test_input), reconstructed_model.predict(test_input)
)

自定义网络层

import keras.backend as K
from keras.layers import *
from keras.models import *
import numpy as npdef sub_mean(x):x-=x/2return xclass MyLayer(Layer):def __init__(self, output_dim, **kw):self.output_dim = output_dimsuper(MyLayer, self).__init__(**kw)def build(self, input_shape):input_dim = input_shape[1]inital_SCALER = np.ones((input_dim,self.output_dim))self.SCALER = K.variable(inital_SCALER)self.trainable_weights = [self.SCALER]super(MyLayer, self).build(input_shape)def call(self, x, mask=None):x = K.dot(x,self.SCALER)return xdef compute_output_shape(self, input_shape):return (input_shape[0],self.output_dim)def get_submean_model():model = Sequential()model.add(Dense(5, input_dim=7))model.add(MyLayer(1))model.add(Lambda(sub_mean,output_shape=lambda input_shape:input_shape))model.compile(optimizer='rmsprop', loss='mse')return model
model = get_submean_model()
model.summary()
import tensorflow as tf
from keras.layers import *
from keras.models import *class CustomDense(Layer):def __init__(self, units=32):super(CustomDense, self).__init__()self.units = unitsdef build(self, input_shape):self.w = self.add_weight(shape=(input_shape[-1], self.units),initializer="random_normal",trainable=True,)self.b = self.add_weight(shape=(self.units,), initializer="random_normal", trainable=True)def call(self, inputs):return tf.matmul(inputs, self.w) + self.bdef get_config(self):return {"units": self.units}inputs = Input((4,))
outputs = CustomDense(10)(inputs)model = Model(inputs, outputs)
model.summary()
config = model.get_config()
new_model = Model.from_config(config, custom_objects={"CustomDense": CustomDense})
new_model.summary()
out = new_model(tf.zeros((2,4)))
out.shape

获得某一层参数

layer = layers.Dense(3)
print(layer.weights)  # Emptyx=tf.zeros((2,3))
out=layer(x)
out.shape,layer.weights
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu", input_shape=(4,)))model.summary()

常用的优化器

from keras.optimizers import RMSprop,Adam,SGD,Adadelta
m_sgd = SGD(lr=0.01,momentum=0.9,decay=1e-3,nesterov=False)
from keras.losses import *
from keras.optimizers import *
model.compile(optimizer=RMSprop(1e-3),loss={"priority": BinaryCrossentropy(from_logits=True),"department": CategoricalCrossentropy(from_logits=True),},metrics=["acc"],loss_weights={"priority": 1.0, "department": 0.2},
)

常用的损失函数

from keras.losses import mean_squared_error,sparse_categorical_crossentropy,binary_crossentropyfrom keras.optimizers import Adam,SGDdef dice_coef_loss(y_true, y_pred):def dice_coef(y_true, y_pred, smooth=1):intersection = K.sum(y_true * y_pred, axis=[1, 2, 3])union = K.sum(y_true, axis=[1, 2, 3]) + K.sum(y_pred, axis=[1, 2, 3])return K.mean((2. * intersection + smooth) / (union + smooth), axis=0)return 1 - dice_coef(y_true, y_pred, smooth=1)# 自定义损失函数
def IoU(y_true, y_pred, eps=1e-6):if K.max(y_true) == 0.0:return IoU(1-y_true, 1-y_pred) ## empty image; calc IoU of zerosintersection = K.sum(y_true * y_pred, axis=[1,2,3])union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3]) - intersectionreturn K.mean( (intersection + eps) / (union + eps), axis=0)model.compile(optimizer=Adam(lr=0.001),loss=dice_coef_loss, metrics=[IoU])

常用的指标验证函数

"""
categorical_accuracy
accuracy
binary_accuracy
mse
mape
top_k_categorical_accuracy
"""model.compile(loss="mse", optimizer=RMSprop(lr=0.001),metrics=['mape'])
# 自定义验证指标函数
def define_rmse(y_true, y_pred):return K.sqrt(K.mean(K.square(y_true - y_pred), axis=-1))model.compile(optimizer='rmsprop',metrics=[define_rmse],loss = define_rmse)

训练过程

# train model
from keras.callbacks import *callbacks = [ModelCheckpoint('./best_model.h5', save_weights_only=True, save_best_only=True, mode='min',verbose=1),ReduceLROnPlateau(monitor='val_loss',factor=0.6,patience=6,mode='min',verbose=1),EarlyStopping(monitor='val_loss', patience=30, verbose=1),
]history = model.fit_generator(train_dataloader, steps_per_epoch=len(train_dataloader), epochs=EPOCHS,  callbacks=callbacks, validation_data=valid_dataloader, validation_steps=len(valid_dataloader),verbose=1)## train modelhistory = model.fit(x_train, y_train, batch_size=16 * 4, epochs=120, verbose=1, validation_data=(x_test, y_test),callbacks=[checkpoint, early_stopping,r_lr],verbose=1)

预测阶段

scores = model.evaluate_generator(val_dataloader)
scores = model.predict_generator(test_dataloader)scores = model.evaluate(x = val_train, y = val_label,batch_size = None, verbose = 1)
pred = model.predict(np.expand_dims(image, axis=0))
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
units = 32
timesteps = 10
input_dim = 5# Define a Functional model
inputs = keras.Input((None, units))
x = layers.GlobalAveragePooling1D()(inputs)
outputs = layers.Dense(1)(x)
model = keras.Model(inputs, outputs)class CustomRNN(layers.Layer):def __init__(self):super(CustomRNN, self).__init__()self.units = unitsself.projection_1 = layers.Dense(units=units, activation="tanh")self.projection_2 = layers.Dense(units=units, activation="tanh")# Our previously-defined Functional modelself.classifier = modeldef call(self, inputs):outputs = []state = tf.zeros(shape=(inputs.shape[0], self.units))for t in range(inputs.shape[1]):x = inputs[:, t, :]h = self.projection_1(x)y = h + self.projection_2(state)state = youtputs.append(y)features = tf.stack(outputs, axis=1)return self.classifier(features)rnn_model = CustomRNN()
out = rnn_model(tf.zeros((1, timesteps, input_dim)))
print(out.shape)
(1, 1)

keras 模型与pytorch模型

二维卷积层(keras vs pytorch)

import numpy as np
import torch
import torch.nn as nn
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers#initialize the layers respectively
torch_layer = nn.Conv2d(    in_channels=3,out_channels=32,kernel_size=(3, 3),stride=(1, 1)
)
torch_model = nn.Sequential(# nn.ZeroPad2d((2,3,2,3)),torch_layer)tf_layer = layers.Conv2D(filters=32,kernel_size=(3, 3),strides=(1, 1),# padding='same',# use_bias=False
)tf_model = keras.Sequential([# layers.ZeroPadding2D((3, 3)),tf_layer])#setting weights in torch layer and tf layer respectively
torch_weights = np.random.rand(32, 3, 3, 3)
torch_bias = np.random.rand(32)
tf_weights = np.transpose(torch_weights, (2, 3, 1, 0))
tf_bias = torch_bias## 赋值固定的权重
torch_layer.weight = torch.nn.Parameter(torch.Tensor(torch_weights))
torch_layer.bias = torch.nn.Parameter(torch.Tensor(torch_bias))tf_model(np.zeros((1,256,256,3)))
# tf_layer.kernel.assign(tf_weights)
tf_layer.weights[0].assign(tf_weights)
tf_layer.weights[1].assign(tf_bias)tf_inputs = np.random.rand(1,  256, 256, 3)
torch_inputs =torch.Tensor(np.transpose(tf_inputs, (0, 3 ,1,2)))with torch.no_grad():torch_output = torch_model(torch_inputs)
tf_output = tf_model(tf_inputs)
print(tf_output.numpy().shape, torch_output.shape)
np.allclose(tf_output.numpy() ,np.transpose(torch_output.numpy(),(0, 2, 3, 1))) #True
(1, 254, 254, 32) torch.Size([1, 32, 254, 254])True

BatchNormal层(keras vs pytorch)


tf_inputs = np.random.rand(1,  12, 12, 32)
layer =layers.BatchNormalization() 
layer(tf_inputs)
weights = layer.get_weights() # gamma,beta,mean,var
for layer in weights:print(layer.shape)
(32,)
(32,)
(32,)
(32,)
torch_layer = nn.BatchNorm2d(32)
torch_layer.weight,torch_layer.bias
(Parameter containing:tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],requires_grad=True),Parameter containing:tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0., 0., 0., 0., 0., 0., 0., 0.], requires_grad=True))
import numpy as np
import torch
import torch.nn as nn
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers#initialize the layers respectively
torch_layer = nn.BatchNorm2d(32,eps=1e-05, momentum=0.1)  #weight(gamma)和bias(beta)将被使用
torch_model = nn.Sequential(# nn.ZeroPad2d((2,3,2,3)),torch_layer)tf_layer = layers.BatchNormalization( momentum=0.1,epsilon=1e-05,)tf_model = keras.Sequential([# layers.ZeroPadding2D((3, 3)),tf_layer])#setting weights in torch layer and tf layer respectively
weights = np.random.rand(32)
bias = np.random.rand(32)
## 赋值固定的权重
torch_layer.weight = torch.nn.Parameter(torch.Tensor(weights))
torch_layer.bias = torch.nn.Parameter(torch.Tensor(bias))tf_model(np.zeros((1,12,12,32)))
# tf_layer.kernel.assign(tf_weights)
tf_layer.weights[0].assign(weights)
tf_layer.weights[1].assign(bias)tf_inputs = np.random.rand(1,  12, 12, 32)
torch_inputs =torch.Tensor(np.transpose(tf_inputs, (0, 3 ,1,2)))
tf_layer.weights[2].assign(tf_inputs.mean(axis=(0,1,2)))
tf_layer.weights[3].assign(tf_inputs.std(axis=(0,1,2)))with torch.no_grad():torch_output = torch_model(torch_inputs)
tf_output = tf_model(tf_inputs)
print(tf_output.numpy().shape, torch_output.shape)
print(np.allclose(tf_output.numpy() ,np.transpose(torch_output.numpy(),(0, 2, 3, 1)))) #True
tf_output[0,0,0,:10],np.transpose(torch_output.numpy(),(0, 2, 3, 1))[0,0,0,:10]
(1, 12, 12, 32) torch.Size([1, 32, 12, 12])
False(<tf.Tensor: shape=(10,), dtype=float32, numpy=array([ 0.45506844, -0.12573612,  0.81879985,  0.08219968,  0.08907801,0.88896   ,  0.6723665 ,  0.9736586 , -0.1965737 ,  0.38121822],dtype=float32)>,array([ 0.53097904, -0.34610078,  0.8367056 , -0.046165  , -0.2674462 ,0.953462  ,  0.69444454,  1.0367548 , -0.36438996,  0.60396177],dtype=float32))

最大池化层(keras vs pytorch)

import numpy as np
import torch
import torch.nn as nn
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers#prepare inputs and do inference
# torch_inputs = torch.Tensor(np.random.rand(1, 3, 256, 256))
# tf_inputs = np.transpose(torch_inputs.numpy(), (0, 2, 3, 1))
tf_inputs = np.random.rand(1,  256, 256, 3)
torch_inputs =torch.Tensor(np.transpose(tf_inputs, (0, 3 ,1,2)))torch_layer =  nn.MaxPool2d(2)
torch_model = nn.Sequential(torch_layer)
tf_layer = layers.MaxPooling2D(pool_size=(2, 2))
tf_model = keras.Sequential([tf_layer])with torch.no_grad():torch_output = torch_model(torch_inputs)
tf_output = tf_model.predict(tf_inputs)
print(tf_output.shape, torch_output.shape)
np.allclose(tf_output ,np.transpose(torch_output.numpy(),(0, 2, 3, 1))) #True
(1, 128, 128, 3) torch.Size([1, 3, 128, 128])
True

全连接层输出(keras vs pytorch)

import numpy as np
import torch
import torch.nn as nn
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers#initialize the layers respectively
torch_layer = nn.Linear(256,10)
torch_model = nn.Sequential( torch_layer)tf_layer = layers.Dense(10,activation=None)
tf_model = keras.Sequential([ tf_layer])#setting weights in torch layer and tf layer respectively
torch_weights = np.random.rand(10,256)
torch_bias = np.random.rand(10)tf_weights = np.transpose(torch_weights, (1, 0))
tf_bias = torch_bias## 赋值固定的权重
torch_layer.weight = torch.nn.Parameter(torch.Tensor(torch_weights))
torch_layer.bias = torch.nn.Parameter(torch.Tensor(torch_bias))
tf_model(np.zeros((4,256)))
tf_layer.weights[0].assign(tf_weights)
tf_layer.weights[1].assign(tf_bias)inputs = torch.Tensor(np.random.rand(4,  256))
with torch.no_grad():torch_output = torch_model(inputs)
tf_output = tf_model(inputs.numpy())
print(tf_output.numpy().shape, torch_output.shape)
np.allclose(tf_output.numpy() ,torch_output.numpy()) #True
(4, 10) torch.Size([4, 10])True

Flatten vs view() (keras vs pytorch)

import numpy as np
import torch
import torch.nn as nn
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
np.set_printoptions(precision=4)
torch.set_printoptions(precision=4)#initialize the layers respectivelytf_layer = layers.Flatten()
tf_model = keras.Sequential([ tf_layer])tf_inputs = np.random.rand(2,2,2,3)
torch_inputs =torch.Tensor(tf_inputs) #np.transpose(tf_inputs, (0, 3, 1, 2)))
print(tf_inputs.shape, torch_inputs.shape)
with torch.no_grad():torch_output =  torch.flatten(torch_inputs,start_dim=1)
tf_output = tf_model(tf_inputs)
print(tf_output.numpy().shape, torch_output.shape)
np.allclose(tf_output.numpy() ,torch_output.numpy()) #True
(2, 2, 2, 3) torch.Size([2, 2, 2, 3])
(2, 12) torch.Size([2, 12])
True

技术交流与资料获取

技术要学会交流、分享,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

资料干货、数据、技术交流提升,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

技术交流、代码、数据获取方式如下

方式①、微信搜索公众号:Python学习与数据挖掘,后台回复:交流
方式②、添加微信号:dkl88194,备注:交流

我们打造了《100个超强算法模型》,特点:从0到1轻松学习,原理、代码、案例应有尽有,所有的算法模型都是按照这样的节奏进行表述,所以是一套完完整整的案例库。

很多初学者是有这么一个痛点,就是案例,案例的完整性直接影响同学的兴致。因此,我整理了 100个最常见的算法模型,在你的学习路上助推一把!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/603552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Keil5,ARM编译器 软件优化注意事项

优化C代码中的环路终止 循环是大多数程序中的常见结构。由于大量的执行时间通常花费在循环中&#xff0c;因此值得关注时间关键循环。 如果不谨慎地编写&#xff0c;环路终止条件可能会导致大量开销。在可能的情况下&#xff1a; 使用简单的终止条件。 写入倒计时到零循环。…

MySQL三种常见存储引擎【理论】【需动手操作】

先放一个大佬的博客 等以后有时间按大佬写的 动手操作一下 链接 MySOL 的存储引擎是指 MySOL 数据库管理系统中用于处理数据存诸和检索的组件。 MySOL 常用的存储引擎有以下几个: InnoDB: InnoDB 是 MySQL(5.5)的默认存储引擎&#xff0c;支持事务处理、行级锁定和物理外键约…

2024年超详细的Python3学习路径规划

前言 基于Python3.5 1.第一阶段基础&#xff08;必须&#xff09; Python3 环境搭建Python3 基础语法Python3 基本数据类型Python3 数据类型转换Python3 解释器Python3 注释Python3 运算符Python3 数字(Number)Python3 字符串Python3 列表Python3 元组Python3 字典Python3 集…

dnSpy调试工具二次开发1-新增菜单

测试环境&#xff1a; window 10 visual studio 2019 版本号&#xff1a;16.11.15 .net framework 4.8 开发者工具包 下载 .NET Framework 4.8 | 免费官方下载 .net 5开发者工具包 下载 .NET 5.0 (Linux、macOS 和 Windows) 利用git拉取代码(源码地址&#xff1a;Gi…

启动IDEA报错,web servcer failed to start.port 8080 was already in use.

启动IDEA报错&#xff0c;web servcer failed to start.port 8080 was already in use. 问题现状 启动IDEA失败&#xff0c;端口被占用。 解决办法&#xff1a; 使用netstat -ano指令&#xff0c;查看端口占用情况 因为我是win11的系统&#xff0c;使用指令时出现如下提示。…

【IC设计】移位寄存器

目录 理论讲解背景介绍什么是移位寄存器按工作模式分类verilog语法注意事项 设计实例循环移位寄存器算术双向移位寄存器5位线性反馈移位寄存器伪随机码发生器3位线性反馈移位寄存器32位线性反馈移位寄存器串行移位寄存器&#xff08;打4拍&#xff09;双向移位寄存器&#xff1…

c语言题目之统计二级制数中1的个数

文章目录 题目一、方法1二、方法2三&#xff0c;方法3总结 题目 统计二进制数中1的个数 输入一行&#xff0c;输出一行 输入&#xff1a; 输入一个整数 输出&#xff1a; 输出存储在内存中二进制的1的个数 一、方法1 之前的文章中&#xff0c;小编写了有关于内存在二进制中的存…

Fiddler工具 — 8.会话列表(Session List)

1、会话列表说明 Fiddler抓取到的每条HTTP请求&#xff08;每一条称为一个session&#xff09;。 主要包含了请求的ID编号、状态码、协议、主机名、URL、内容类型、body大小、进程信息、自定义备注等信息。如下图&#xff1a; 说明&#xff1a; 名称含义#抓取HTTP Request的顺…

Ribbon相关问题及答案(2024)

1、Ribbon是什么&#xff0c;它在微服务架构中扮演什么角色&#xff1f; Ribbon是一个客户端负载均衡器&#xff0c;它在微服务架构中扮演着关键性的角色。Ribbon的设计理念是在客户端进行服务发现和负载均衡&#xff0c;这种方式不同于传统的通过中心化的负载均衡器&#xff…

YHZ018 Python 运算符优先级

资源编号&#xff1a;YHZ018 配套视频&#xff1a;https://www.bilibili.com/video/BV1zy4y1Z7nk?p19 YHZ018&#xff1a;运算符优先级 &#x1fabf; 运算符优先级 Python支持多种运算符&#xff0c;下表按照优先级从高到低的顺序列出了所有运算符。运算符的优先级决定了在表…

面试算法90:环形房屋偷盗

题目 一条环形街道上有若干房屋。输入一个数组表示该条街道上的房屋内财产的数量。如果这条街道上相邻的两幢房屋被盗就会自动触发报警系统。请计算小偷在这条街道上最多能偷取的财产的数量。例如&#xff0c;街道上5家的财产用数组[2&#xff0c;3&#xff0c;4&#xff0c;5…

js实现全选按钮,反选

点击全选按钮&#xff0c;下面的按钮全部选中&#xff1b;再次点击&#xff0c;全部取消选择。 点击下面的按钮时&#xff0c;检查下面的按钮是不是全部都选中&#xff0c;如果全部选中了&#xff0c;需要修改全选按钮的选中状态为ture。 全选反选 <!DOCTYPE html> <…

Linux系统IO—探索输入输出操作的奥秘

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;HEART BEAT—YOASOBI 2:20━━━━━━️&#x1f49f;──────── 5:35 &#x1f504; ◀️ ⏸ ▶️ ☰ …

c++之迭代器

目录 一、迭代器 二、几种常见的迭代器类型 三、使用迭代器时注意事项 一、迭代器 在C中&#xff0c;迭代器是一种用于遍历容器元素的对象。迭代器提供了一种通用的方式来访问各种不同类型的容器&#xff0c;如数组、向量、列表、集合和映射等。 使用迭代器可以避免直接操作…

三、Qt核心与Qt类库

一、Qt核心&#xff1a;元对象系统 1、Qt核心特点 Qt对标准C进行了扩展&#xff0c;引入了一些新的概念和功能元对象编译器&#xff08;MOC&#xff09;是一个预处理器&#xff0c;先将Qt的特性程序转为标准C程序&#xff0c;再由标准C编译器进行编译Qt为C语言增加的特性在Qt…

提升开发效率:npm包管理器的使用技巧

文章目录 一、npm简介二、npm的基本操作1. 安装Node.js和npm2. 创建和管理项目3. 安装依赖4. 卸载依赖5. 更新依赖 三、npm的高级特性1. 使用不同版本的依赖项2. 查看已安装的依赖项和它们的版本信息3. 运行脚本命令 《Node.js从入门到精通&#xff08;软件开发视频大讲堂&…

09-生成器模式(Builder)模式

意图 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 理解 如果构建一个对象的的过程会比较复杂&#xff0c;或者说在写代码的过程中&#xff0c;需要比较频繁地构建某个对象&#xff0c;那么可以针对这个对象写一个专门用于构建这…

2024前端炫酷源码分享(附效果图及在线演示)

分享10款非常有趣的前端特效源码 其中包含css动画特效、js原生特效、svg特效以及小游戏等 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 GSAP-火箭动画特效 GSAP 火箭动画 当氮气充足的情况下 火箭会冲出 并继续飞行 图片…

C#,字符串匹配算法(模式搜索)Z算法的源代码与数据可视化

Z算法也是模式搜索&#xff08;Pattern Search Algorithm&#xff09;的常用算法。 本文代码的运算效果&#xff1a; 一、Z 算法 线性时间模式搜索算法的Z算法&#xff0c;在线性时间内查找文本中模式的所有出现。 假设文本长度为 n&#xff0c;模式长度为 m&#xff0c;那么…

【Spring Cloud 】进阶之Config配置中心

目录 config大致的一个思路&#xff1a; 二&#xff0c;前期准备 2.1导入依赖 2.2编写bootstrop.yml&#xff1a; 三&#xff0c;编写Controller类 3.1获取单个配置类信息 3.2获取多个配置类信息 &#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f3…