matlab2017调用vgg19,VGG19模型训练+读取

VGG-19的介绍和训练这里不做说明,网上资源很多,而且相对比较简单.

本博文主要介绍VGG-19模型调用官方已经训练好的模型,进行测试使用.

[TOC]

VGG-19模型简单介绍

e96b7a9b4229

VGG模型使用

e96b7a9b4229

VGG结构模型

e96b7a9b4229

VGG具体参数模型

VGG-19模型文件介绍

这里是重难点,VGG-19模型存储的方式有点复杂

可以通过作者文档说明去查看

可以通过在线调试查看结构,对比模型得出结论

分析模型文件

首先我们通过scipy模块(当然你可以用其它方式入opencv / sklearn等)读取scipy.io.loadmat()文件

data = scipy.io.loadmat(data_path)

接下来使用Pycharm在线查看data数据结构:

总共有很多参数,我们只关心我们需要关注的,W和B在哪里就行了

注意这里还有一个mean(平均值),因为VGG使用了图像预处理方式是 input - mean,当然这种处理方式在现在看来不怎么好,但是现在我们用人家的模型,需要遵照人家的意思.

这里主要关注"layers"和"normalization"

e96b7a9b4229

data内存一

mean值查看

首先查看normalization的mean值:

注意我们使用的是RGB输入,且图像大小为224*224,也就是说图像是[1 * 224 * 224 *3]格式

那么我们的mean肯定就是[X,Y,Z]的格式,因为是RGB的平均值

这里使用笨方法,直接带入:

data["normalization"][0][0][0][0][0]

先看大概看一下数据结构,然后一个一个测试,因为在线调试,这样很快,比你精确的去找要快很多.

e96b7a9b4229

image

Weight和Bias查看

e96b7a9b4229

layer(一)

这里和mean查看方法不同,W和B得自习查看数据结构,因为太复杂了

从下面的图看到存储的43个参数

注意里面的Relu是没有数据的,因为Relu就是一个函数

注意Pool的参数是固定的,因为大小为:[1,2,2,1],步长[1,2,2,1],这里可以自己写,也可以读取参数

Weight Bias是存放在Relu Pool 中间的,而且两个值存在一起的.

后期代码需要进一步处理,后面会说到.

再不明白的,自己画个VGG-19网络就知道了.

e96b7a9b4229

layer(二)

读取代码

mean = data["normalization"][0][0][0][0][0]

data['layers'][0][i][0][0][0][0])

读取模型

这里默认大家已经会CNN的基本操作了,代码不做详细说明

import tensorflow as tf

import numpy as np

import matplotlib.pyplot as plt

import os

import scipy.io

import scipy.misc

from imagenet_classes import class_names

def _conv_layer(input,weight,bias):

conv = tf.nn.conv2d(input,weight,strides=[1,1,1,1],padding="SAME")

return tf.nn.bias_add(conv,bias)

def _pool_layer(input):

return tf.nn.max_pool(input,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")

def preprocess(image,mean_pixel):

'''简单预处理,全部图片减去平均值'''

return image-mean_pixel

def unprocess(image,mean_pixel):

return image+mean_pixel

def imread(path):

return scipy.misc.imread(path)

def imsave(image,path):

img = np.clip(image,0,255).astype(np.int8)

scipy.misc.imsave(path,image)

def net(data_path,input_image,sess=None):

"""

读取VGG模型参数,搭建VGG网络

:param data_path: VGG模型文件位置

:param input_image: 输入测试图像

:return:

"""

layers = (

'conv1_1', 'conv1_2', 'pool1',

'conv2_1', 'conv2_2', 'pool2',

'conv3_1', 'conv3_2', 'conv3_3','conv3_4', 'pool3',

'conv4_1', 'conv4_2', 'conv4_3','conv4_4', 'pool4',

'conv5_1', 'conv5_2', 'conv5_3','conv5_4', 'pool5',

'fc1' , 'fc2' , 'fc3' ,

'softmax'

)

data = scipy.io.loadmat(data_path)

mean = data["normalization"][0][0][0][0][0]

input_image = np.array([preprocess(input_image, mean)]).astype(np.float32)#去除平均值

net = {}

current = input_image

net["src_image"] = tf.constant(current) # 存储数据

count = 0 #计数存储

for i in range(43):

if str(data['layers'][0][i][0][0][0][0])[:4] == ("relu"):

continue

if str(data['layers'][0][i][0][0][0][0])[:4] == ("pool"):

current = _pool_layer(current)

elif str(data['layers'][0][i][0][0][0][0]) == ("softmax"):

current = tf.nn.softmax(current)

elif i == (37):

shape = int(np.prod(current.get_shape()[1:]))

current = tf.reshape(current, [-1, shape])

kernels, bias = data['layers'][0][i][0][0][0][0]

kernels = np.reshape(kernels,[-1,4096])

bias = bias.reshape(-1)

current = tf.nn.relu(tf.add(tf.matmul(current,kernels),bias))

elif i == (39):

kernels, bias = data['layers'][0][i][0][0][0][0]

kernels = np.reshape(kernels,[4096,4096])

bias = bias.reshape(-1)

current = tf.nn.relu(tf.add(tf.matmul(current,kernels),bias))

elif i == 41:

kernels, bias = data['layers'][0][i][0][0][0][0]

kernels = np.reshape(kernels, [4096, 1000])

bias = bias.reshape(-1)

current = tf.add(tf.matmul(current, kernels), bias)

else:

kernels,bias = data['layers'][0][i][0][0][0][0]

#注意VGG存储方式为[,]

#kernels = np.transpose(kernels,[1,0,2,3])

bias = bias.reshape(-1)#降低维度

current = tf.nn.relu(_conv_layer(current,kernels,bias))

net[layers[count]] = current #存储数据

count += 1

return net, mean

if __name__ == '__main__':

VGG_PATH = os.getcwd()+"/imagenet-vgg-verydeep-19.mat"

input_image = scipy.misc.imread("234.jpeg")

input_image = scipy.misc.imresize(input_image,[224,224,3])

shape = (1, input_image.shape[0], input_image.shape[1], input_image.shape[2])

#image = tf.placeholder('float', shape=shape)

with tf.Session() as sess:

nets, mean_pixel, = net(VGG_PATH, input_image, sess=sess)

#print(sess.run(nets,feed_dict={image:input_image}))

nets = sess.run(nets)

'''

for key, values in nets.items():

if len(values.shape)<4:

continue

plt.figure(key)

plt.matshow(values[0, :, :, 0],)

plt.title(key)

plt.colorbar()

plt.show()

'''

#打印概率最大的三个数据

net_sort = list(reversed(np.argsort(nets["softmax"]).reshape(-1).tolist()))

net_softmax = nets["softmax"].reshape(-1).tolist()

for i in range(3):

print(class_names[net_sort[i]],": ",net_softmax[net_sort[i]])

输入图片:

e96b7a9b4229

测试图片

结果显示:

e96b7a9b4229

结果图

百度验证:

e96b7a9b4229

验证图

完整模型下载地址:

网盘老是被封,请留言邮箱发送

训练代码

以下是训练的代码:

这部分随便看看就好,比较简单~~主要看思想和细节!

########################################################################################

# Davi Frossard, 2016 #

# VGG16 implementation in TensorFlow #

# Details: #

# http://www.cs.toronto.edu/~frossard/post/vgg16/ #

# #

# Model from https://gist.github.com/ksimonyan/211839e770f7b538e2d8#file-readme-md #

# Weights from Caffe converted using https://github.com/ethereon/caffe-tensorflow #

########################################################################################

import tensorflow as tf

import numpy as np

from scipy.misc import imread, imresize

from imagenet_classes import class_names

class vgg16:

def __init__(self, imgs, weights=None, sess=None):

self.imgs = imgs

self.convlayers()

self.fc_layers()

self.probs = tf.nn.softmax(self.fc3l)

if weights is not None and sess is not None:

self.load_weights(weights, sess)

def convlayers(self):

self.parameters = []

# zero-mean input

with tf.name_scope('preprocess') as scope:

mean = tf.constant([123.68, 116.779, 103.939], dtype=tf.float32, shape=[1, 1, 1, 3], name='img_mean')

images = self.imgs-mean

# conv1_1

with tf.name_scope('conv1_1') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 3, 64], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(images, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv1_1 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# conv1_2

with tf.name_scope('conv1_2') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 64], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.conv1_1, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv1_2 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# pool1

self.pool1 = tf.nn.max_pool(self.conv1_2,

ksize=[1, 2, 2, 1],

strides=[1, 2, 2, 1],

padding='SAME',

name='pool1')

# conv2_1

with tf.name_scope('conv2_1') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 128], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.pool1, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv2_1 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# conv2_2

with tf.name_scope('conv2_2') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 128], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.conv2_1, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv2_2 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# pool2

self.pool2 = tf.nn.max_pool(self.conv2_2,

ksize=[1, 2, 2, 1],

strides=[1, 2, 2, 1],

padding='SAME',

name='pool2')

# conv3_1

with tf.name_scope('conv3_1') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 256], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.pool2, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv3_1 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# conv3_2

with tf.name_scope('conv3_2') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.conv3_1, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv3_2 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# conv3_3

with tf.name_scope('conv3_3') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.conv3_2, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv3_3 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# pool3

self.pool3 = tf.nn.max_pool(self.conv3_3,

ksize=[1, 2, 2, 1],

strides=[1, 2, 2, 1],

padding='SAME',

name='pool3')

# conv4_1

with tf.name_scope('conv4_1') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 512], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.pool3, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv4_1 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# conv4_2

with tf.name_scope('conv4_2') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.conv4_1, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv4_2 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# conv4_3

with tf.name_scope('conv4_3') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.conv4_2, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv4_3 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# pool4

self.pool4 = tf.nn.max_pool(self.conv4_3,

ksize=[1, 2, 2, 1],

strides=[1, 2, 2, 1],

padding='SAME',

name='pool4')

# conv5_1

with tf.name_scope('conv5_1') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.pool4, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv5_1 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# conv5_2

with tf.name_scope('conv5_2') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.conv5_1, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv5_2 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# conv5_3

with tf.name_scope('conv5_3') as scope:

kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,

stddev=1e-1), name='weights')

conv = tf.nn.conv2d(self.conv5_2, kernel, [1, 1, 1, 1], padding='SAME')

biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),

trainable=True, name='biases')

out = tf.nn.bias_add(conv, biases)

self.conv5_3 = tf.nn.relu(out, name=scope)

self.parameters += [kernel, biases]

# pool5

self.pool5 = tf.nn.max_pool(self.conv5_3,

ksize=[1, 2, 2, 1],

strides=[1, 2, 2, 1],

padding='SAME',

name='pool4')

def fc_layers(self):

# fc1

with tf.name_scope('fc1') as scope:

shape = int(np.prod(self.pool5.get_shape()[1:]))

fc1w = tf.Variable(tf.truncated_normal([shape, 4096],

dtype=tf.float32,

stddev=1e-1), name='weights')

fc1b = tf.Variable(tf.constant(1.0, shape=[4096], dtype=tf.float32),

trainable=True, name='biases')

pool5_flat = tf.reshape(self.pool5, [-1, shape])

fc1l = tf.nn.bias_add(tf.matmul(pool5_flat, fc1w), fc1b)

self.fc1 = tf.nn.relu(fc1l)

self.parameters += [fc1w, fc1b]

# fc2

with tf.name_scope('fc2') as scope:

fc2w = tf.Variable(tf.truncated_normal([4096, 4096],

dtype=tf.float32,

stddev=1e-1), name='weights')

fc2b = tf.Variable(tf.constant(1.0, shape=[4096], dtype=tf.float32),

trainable=True, name='biases')

fc2l = tf.nn.bias_add(tf.matmul(self.fc1, fc2w), fc2b)

self.fc2 = tf.nn.relu(fc2l)

self.parameters += [fc2w, fc2b]

# fc3

with tf.name_scope('fc3') as scope:

fc3w = tf.Variable(tf.truncated_normal([4096, 1000],

dtype=tf.float32,

stddev=1e-1), name='weights')

fc3b = tf.Variable(tf.constant(1.0, shape=[1000], dtype=tf.float32),

trainable=True, name='biases')

self.fc3l = tf.nn.bias_add(tf.matmul(self.fc2, fc3w), fc3b)

self.parameters += [fc3w, fc3b]

def load_weights(self, weight_file, sess):

weights = np.load(weight_file)

keys = sorted(weights.keys())

for i, k in enumerate(keys):

print i, k, np.shape(weights[k])

sess.run(self.parameters[i].assign(weights[k]))

if __name__ == '__main__':

sess = tf.Session()

imgs = tf.placeholder(tf.float32, [None, 224, 224, 3])

vgg = vgg16(imgs, 'vgg16_weights.npz', sess)

img1 = imread('laska.png', mode='RGB')

img1 = imresize(img1, (224, 224))

prob = sess.run(vgg.probs, feed_dict={vgg.imgs: [img1]})[0]

preds = (np.argsort(prob)[::-1])[0:5]

for p in preds:

print class_names[p], prob[p]

参考资料

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

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

相关文章

LeetCode 1504. 统计全 1 子矩形(记录左侧的连续1的个数)

文章目录1. 题目2. 解题1. 题目 给你一个只包含 0 和 1 的 rows * columns 矩阵 mat &#xff0c; 请你返回有多少个 子矩形 的元素全部都是 1 。 示例 1&#xff1a; 输入&#xff1a;mat [[1,0,1],[1,1,0],[1,1,0]] 输出&#xff1a;13 解释&#xff1a; 有 6 个 1x1 的矩…

matlab中ode23s使用方法,MATLAB中ode23函数,龙格库塔函数

今天说一说MATLAB中ode23函数的原理&#xff0c;在网上看了好多&#xff0c;但是不知道是怎么计算的&#xff0c;就知道是那么用的&#xff0c;但是最后结果咋回事不知道&#xff0c;今天来讲一讲是怎么计算的。首先来个程序&#xff1a;function feg6fun(t,y)f-y^3-2;end上面是…

LeetCode 1503. 所有蚂蚁掉下来前的最后一刻(脑筋急转弯)

文章目录1. 题目2. 解题1. 题目 有一块木板&#xff0c;长度为 n 个 单位 。一些蚂蚁在木板上移动&#xff0c;每只蚂蚁都以 每秒一个单位 的速度移动。其中&#xff0c;一部分蚂蚁向 左 移动&#xff0c;其他蚂蚁向 右 移动。 当两只向 不同 方向移动的蚂蚁在某个点相遇时&a…

LeetCode 1246. 删除回文子数组(区间DP)

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 arr&#xff0c;每一次操作你都可以选择并删除它的一个 回文 子数组 arr[i], arr[i1], ..., arr[j]&#xff08; i < j&#xff09;。 注意&#xff0c;每当你删除掉一个子数组&#xff0c;右侧元素都会自行向前移动填补空…

LeetCode 573. 松鼠模拟(数学)*

文章目录1. 题目2. 解题1. 题目 现在有一棵树&#xff0c;一只松鼠和一些坚果。位置由二维网格的单元格表示。 你的目标是找到松鼠收集所有坚果的最小路程&#xff0c;且坚果是一颗接一颗地被放在树下。 松鼠一次最多只能携带一颗坚果&#xff0c;松鼠可以向上&#xff0c;向下…

MySQL索引背后的数据结构及算法原理(转)

摘要 本文以MySQL数据库为研究对象&#xff0c;讨论与数据库索引相关的一些话题。特别需要说明的是&#xff0c;MySQL支持诸多存储引擎&#xff0c;而各种存储引擎对索引的支持也各不相同&#xff0c;因此MySQL数据库支持多种索引类型&#xff0c;如BTree索引&#xff0c;哈希索…

LeetCode 1273. 删除树节点(拓扑排序/DFS)

文章目录1. 题目2. 解题2.1 取巧解2.2 拓扑排序2.3 建图DFS1. 题目 给你一棵以节点 0 为根节点的树&#xff0c;定义如下&#xff1a; 节点的总数为 nodes 个&#xff1b; 第 i 个节点的值为 value[i] &#xff1b; 第 i 个节点的父节点是 parent[i] 。 请你删除节点值之和为…

WinForm邮件内容编辑器的简单实现

1、概述 在WinForm开发中&#xff0c;您可能会碰到发送邮件时内容编辑的问题&#xff0c;大部分开发人员第一个想法是希望将 WinForm中的内容编辑器做到和.NET 中类似FCK一样。今天我们就来介绍下如何实现和FCK一样的内容编辑器功能。 2、正文 邮件内容编辑器的问题,在…

LeetCode 1245. 树的直径(图的最大直径结论)

文章目录1. 题目2. 解题1. 题目 求树的最大直径。 2. 解题 类似题目&#xff1a;LeetCode 5538. 统计子树中城市之间最大距离&#xff08;枚举所有可能图的最大直径&#xff09; 结论&#xff1a;求无权无向图中的最长一条路径 先从任意一点P出发&#xff0c;找到离它最远的…

64 位 win7(2008 r2) 使用PLSQL Developer x86 32bit的解决方法

64 位 win7 使用PLSQL Developer 由于 PLSQL Developer 没有64位版本&#xff0c;所以在64位系统上运行该程序会报错&#xff0c;笔者为这个问题纠结了好几天&#xff0c;后来通过请教Google 动手实践&#xff0c;终于搞定了这个问题。现在把笔者解决的过程记录下来&#xff…

python的序列类型包括哪三类,Python常用的序列类型包括列表、元组和字典三种。...

表示M型&#xff0c;常用统中库管理系数据。边际位人的人消费每增增加加1均收均消倾向个单出数入所费支是指&#xff0c;列类边际消费民的年农倾向村居是(。的家品消庭食9年则2居民城镇出为费支&#xff0c;型包庭以3口镇家若城人计算。括列北省的份控股有及额为年国占河企业国…

LeetCode 545. 二叉树的边界(前序+后序)*

文章目录1. 题目2. 解题1. 题目 给定一棵二叉树&#xff0c;以逆时针顺序从根开始返回其边界。 边界按顺序包括左边界、叶子结点和右边界而不包括重复的结点。 (结点的值可能重复) 左边界的定义是从根到最左侧结点的路径。 右边界的定义是从根到最右侧结点的路径。 若根没有左…

centos 7 ssh 安装mysql,Linux服务器远程ssh为centos7安装MySQL

最近为客户选了个云服务器操作系统选择CentOS 7.0 64位通过ssh远程安装MySQL5.6&#xff0c;与大家分享安装过程ssh远程客户端选择的是xshell,感觉比较好用&#xff0c;可以直接通过绑定的xftp进行远程目录的上传下载操作通过xshell先连接远程服务器&#xff0c;指定服务器ip&a…

LeetCode 333. 最大 BST 子树(递归)*

文章目录1. 题目2. 解题1. 题目 给定一个二叉树&#xff0c;找到其中最大的二叉搜索树&#xff08;BST&#xff09;子树&#xff0c; 其中最大指的是子树节点数最多的。 注意: 子树必须包含其所有后代。 示例: 输入: [10,5,15,1,8,null,7]10 / \ 5 15 / \ \ 1 8 7 输…

LeetCode 663. 均匀树划分(树形DP)

文章目录1. 题目2. 解题1. 题目 给定一棵有 n 个结点的二叉树&#xff0c;你的任务是检查是否可以通过去掉树上的一条边将树分成两棵&#xff0c;且这两棵树结点之和相等。 样例 1: 输入: 5/ \10 10/ \2 3 输出: True 解释: 5/ 10和: 1510/ \2 3和: 15样例 2: 输入…

LeetCode 261. 以图判树(全部连通+边数=V-1)

文章目录1. 题目2. 解题1. 题目 给定从 0 到 n-1 标号的 n 个结点&#xff0c;和一个无向边列表&#xff08;每条边以结点对来表示&#xff09;&#xff0c; 请编写一个函数用来判断这些边是否能够形成一个合法有效的树结构。 示例 1&#xff1a; 输入: n 5, 边列表 edges …

php实现数字滚动效果,vue如何实现数字滚动增加效果?代码示例

项目中需要做数字滚动增加的效果&#xff0c;一开始很懵&#xff0c;研究了一下原理&#xff0c;发现很简单&#xff0c;贴出来分享一下 ^_^数字滚动组件&#xff1a;0props: {time: {type: Number,default: 2},value: {type: Number,default: 720000}},methods: {numberGrow (…

LeetCode 1061. 按字典序排列最小的等效字符串(并查集)

文章目录1. 题目2. 解题1. 题目 给出长度相同的两个字符串&#xff1a;A 和 B&#xff0c;其中 A[i] 和 B[i] 是一组等价字符。 举个例子&#xff0c;如果 A "abc" 且 B "cde"&#xff0c;那么就有 a c, b d, c e。 等价字符遵循任何等价关系的一般…

LeetCode 366. 寻找二叉树的叶子节点(上下翻转二叉树+BFS)

文章目录1. 题目2. 解题1. 题目 给你一棵二叉树&#xff0c;请按以下要求的顺序收集它的全部节点&#xff1a; 依次从左到右&#xff0c;每次收集并删除所有的叶子节点重复如上过程直到整棵树为空 示例: 输入: [1,2,3,4,5]1/ \2 3/ \ 4 5 输出: [[4,5,3],[2],[1]…

白话地图投影之初识地球

本文是Koala带你进入GIS世界的开篇&#xff0c;Koala打算用简单通俗的语言为大家介绍地图投影&#xff0c;帮助GISer理解地图投影的概念。作为进入GIS世界多年的老鸟&#xff0c;Koala也是在不断的实战中才真正理解和掌握地图投影的奥秘。 我们生活的地球长啥模样&#xff1f; …