Jovian
⭐️
Sign In

培训大纲

1. python基础

2. 机器学习基础及实践

3. 深度学习基础及实践

4. DeepSat框架介绍及实践


课程1

python基础介绍

Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。
Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年。
python的定位就是“优雅”,“明确”,“简单”,所以python代码看上去简单易懂,初学者入门很快。

anaconda

python安装

1.官方版

解释器和标准库
下载地址:https://www.python.org/downloads/

2.科学发行版 Anaconda

1.解释器和标准库
2.包含各种常用的科学计算包库(numpy,scipy,pandas...)
3.更强大的第三包库配置工具
下载地址:(推荐使用python3.6版本的anaconda)
使用清华镜像源 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/

anaconda

3.IDEL选择

1.重量级:PyCharm
2.轻量级:vscode、sublime
3.科学玩家:jupyter notebook

4.第三方库安装

1.conda

  • conda install [package]
  • 完美解决包库之间依赖关系

2.pip

  • pip install [package]
  • 最早的python包库管理
  • 包库数量众多

3.源码安装

5. jupyter notebook 使用方法

jupyter


基本数据类型

1. 数字

Python可以处理任意大小的整数,包括负整数,1,100,-1000,0

常见操作符:

  • 加法:+
  • 减法:-
  • 乘法:*
  • 除法:/ (python3中除法都是以浮点型进行运算,即使两个数都是整数)
  • 取余://
In [6]:
1 + 2
Out[6]:
3
In [7]:
1+100-1000+4
Out[7]:
-895
In [8]:
2.1 + 4.3 * 54
Out[8]:
234.29999999999998
In [9]:
4/2
Out[9]:
2.0
In [10]:
print(type(5))
print(type(2))
5/2
<class 'int'> <class 'int'>
Out[10]:
2.5
In [11]:
5//2
Out[11]:
2

2. 字符串

字符串是以单引号'或双引号"括起来的任意文本,多行文本用''' ''',对于特殊字符用\进行转义

In [16]:
str1 = 'python'
In [17]:
type(str1)
Out[17]:
str
In [12]:
print("hello 
      
      
      world!") #普通字符
File "<ipython-input-12-afe5422fc634>", line 1 print("hello ^ SyntaxError: EOL while scanning string literal
In [6]:
print('hello world!') #普通字符
print('I\'m learning "Python".') #转移字符,' 和 回车
print(r"I'm learning 'Python'.") #转移字符,用r开头
print('''多行文本开始:
第一行,
第二行,




。。。''') # 多行文本

hello world! I'm learning "Python". I'm learning 'Python'. 多行文本开始: 第一行, 第二行, 。。。

3. 布尔值

布尔值只有True、False两种值

In [7]:
True
Out[7]:
True
In [8]:
False
Out[8]:
False
In [9]:
if True:
    print('this is Ture')
if False:
    print('nothing...')
this is Ture

布尔值可以用and、or和not运算

In [18]:
True and True
Out[18]:
True
In [20]:
True and False
Out[20]:
False
In [21]:
True or False
Out[21]:
True
In [22]:
not True
Out[22]:
False
In [23]:
not False
Out[23]:
True

4. 变量

变量名必须是大小写英文、数字和_的组合,且不能用数字开头,

In [12]:
var = 0
print(type(var))
Var = 'fasdf'
print(type(Var))
var_1 = 111
_var2 = 222
<class 'int'> <class 'str'>
In [13]:
2fdsa = 333 # 错误,不能以数字开头
File "<ipython-input-13-6037f88f9728>", line 1 2fdsa = 333 # 错误,不能以数字开头 ^ SyntaxError: invalid syntax

python是动态语言,因此不会像C语言那样,每个变量有固定的数据类型

In [17]:
pi = 3.1415926
type(pi)
Out[17]:
float
In [18]:
pi = 'pi value is 3.1415926'
type(pi)
Out[18]:
str

5. 列表list & 元组tuple

列表是python内置的数据类型,一种有序的集合,以中括号[]开始和结束,一个列表中可以包含所有数据类型,甚至可以嵌套list

In [1]:
list1 = ['python','石油','北京']
list1
Out[1]:
['python', '石油', '北京']
In [20]:
list2 = ['python','石油','北京', 11, 21, 3.14, True] #多种数据类型
list2
Out[20]:
['python', '石油', '北京', 11, 21, 3.14, True]
In [21]:
#list中嵌套一个list
list3 = ['python','石油','北京', [11, 12, 3.14], True, False] #嵌套list
list3
Out[21]:
['python', '石油', '北京', [11, 12, 3.14], True, False]

5.1 访问元素

In [23]:
#len() 返回list长度
len(list3)
Out[23]:
6
In [33]:
#需要注意,python里面索引从0开始
list3[0]
Out[33]:
'python'
In [31]:
list3[3]
Out[31]:
[11, 12, 3.14]
In [32]:
#索引不能越界
list3[10]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-32-aca6ddb4e8df> in <module>() 1 #下标不能越界 ----> 2 list3[10] IndexError: list index out of range
In [34]:
list3[-6] #倒序访问
Out[34]:
'python'
In [36]:
list3[1:3] # 切片,左闭右开,[1:3]实际是list[1]和list[2]
Out[36]:
['石油', '北京']
In [38]:
#如果list中嵌套list,可以对嵌套的list再索引
list3[3][1]
Out[38]:
12
In [39]:
a=[1,2,3,4,5,6,7,8,9]
In [40]:
#切片时还可以设置步长
a[0:8:3]
Out[40]:
[1, 4, 7]
In [42]:
list3
Out[42]:
['python', '石油', '北京', [11, 12, 3.14], True, False]
In [41]:
list3[0:6:2] # 步长切片
Out[41]:
['python', '北京', True]

5.2 基本操作

In [43]:
# 修改元素
list3[2] = '上海'
list3
Out[43]:
['python', '石油', '上海', [11, 12, 3.14], True, False]
In [44]:
# 删除元素
print('原始:', list3)
list3.pop()  # 删除最后一个元素


print('删除最后一个元素:', list3)
list3.pop(0)  # 删除第一个元素
print('删除第一个元素:', list3)
原始: ['python', '石油', '上海', [11, 12, 3.14], True, False] 删除最后一个元素: ['python', '石油', '上海', [11, 12, 3.14], True] 删除第一个元素: ['石油', '上海', [11, 12, 3.14], True]
In [45]:
# 添加元素
list3.insert(0, '研究所') # insert可以在任意位置添加元素
print(list3)
list3.append('研究所') # append主要是末尾添加元素
print(list3)

['研究所', '石油', '上海', [11, 12, 3.14], True] ['研究所', '石油', '上海', [11, 12, 3.14], True, '研究所']
In [47]:
# 判断元素是否在列表中
'石油' in list3
Out[47]:
True
In [49]:
'java' in list3
Out[49]:
False

5.3元组

tuple和list非常类似,但是tuple一旦初始化就不能修改

In [51]:
tuple1 = ('python','石油','北京')
tuple1
#tuple.append(123) #错误
Out[51]:
('python', '石油', '北京')
In [52]:
tuple1.append(123) #错误
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-52-ee44905aa83f> in <module>() ----> 1 tuple1.append(123) #错误 AttributeError: 'tuple' object has no attribute 'append'
In [53]:
tuple1[0] = 3.14 #错误,不能修改值
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-53-f265224ee11f> in <module>() ----> 1 tuple1[0] = 3.14 #错误,不能修改值 TypeError: 'tuple' object does not support item assignment

6. 字典dict & 集合set

dict,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。dict内部存放的顺序和key放入的顺序是没有关系的。

和list比较,dict有以下几个特点:

  1. 查找和插入的速度极快,不会随着key的增加而变慢;
  2. 需要占用大量的内存,内存浪费多。

而list相反:

  1. 查找和插入的时间随着元素的增加而增加;
  2. 占用空间小,浪费内存很少。

dict是用空间来换取时间的一种方法。

In [54]:
dict1={
    '市':'北京市',
    '区':'海淀区',
    '街道':'中关村东路',
}
In [56]:
dict1['市']
Out[56]:
'北京市'
In [58]:
dict1.get('市')
Out[58]:
'北京市'
In [59]:
dict1['区'] = '朝阳区'
dict1
Out[59]:
{'市': '北京市', '区': '朝阳区', '街道': '中关村东路'}

set

set是无序和无重复元素的集合。
可以使用大括号{ }或者set()函数创建集合,注意:创建一个空集合必须用set()而不是{ },因为{ }是用来创建一个空字典

In [63]:
#创建
s = set('123')
s
Out[63]:
{'1', '2', '3'}
In [64]:
s = {2,3,4}
s
Out[64]:
{2, 3, 4}
In [71]:
s = {2,3,4,5,4} #去重
s
Out[71]:
{2, 3, 4, 5}
In [72]:
#判断元素是否在集合内
3 in s
Out[72]:
True
In [73]:
6 in s
Out[73]:
False

两个集合之间的运算

In [69]:
set_a = set('abcde')
set_b = set('bcdef')
print(set_a)
print(set_b)
{'c', 'a', 'd', 'b', 'e'} {'f', 'c', 'd', 'b', 'e'}
In [74]:
set_a - set_b #集合a中包含而集合b中不包含的元素
Out[74]:
{'a'}
In [76]:
set_a | set_b # 集合a或b中包含的所有元素
Out[76]:
{'a', 'b', 'c', 'd', 'e', 'f'}
In [77]:
set_a & set_b #集合a和b都包含的元素
Out[77]:
{'b', 'c', 'd', 'e'}
In [78]:
set_a ^ set_b #不同时包含于集合a和b的元素
Out[78]:
{'a', 'f'}

set的基本操作

In [79]:
s
Out[79]:
{2, 3, 4, 5}
In [81]:
#将元素x添加到集合中,如果元素已存在,则不进行任何操作。
s.add(6)
s
Out[81]:
{2, 3, 4, 5, 6}
In [82]:
#还有一个方法,也可以添加元素,且参数可以是列表,元组,字典等,update()
s.update((7,8))
s
Out[82]:
{2, 3, 4, 5, 6, 7, 8}
In [83]:
s.update({9,10})
s
Out[83]:
{2, 3, 4, 5, 6, 7, 8, 9, 10}
In [88]:
s.update({'市':'北京市','区':'海淀区','街道':'中关村东路'})
s
Out[88]:
{10, 2, 3, 4, 5, 6, 7, 8, 9, '区', '市', '街道'}
In [89]:
#移除元素,remove()
s.remove(4)
s
Out[89]:
{10, 2, 3, 5, 6, 7, 8, 9, '区', '市', '街道'}
In [90]:
#移除不存在的原始会报错
s.remove(1)
s
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-90-438977af416d> in <module>() 1 #移除不存在的原始会报错 ----> 2 s.remove(1) 3 s KeyError: 1
In [92]:
# 另一个移除集合元素的方法 discard(),元素不存在,不会报错
s.discard(100)
s
Out[92]:
{10, 2, 3, 5, 6, 7, 8, 9, '区', '市', '街道'}

条件判断&循环

1. 条件判断

In [93]:
a = True
a
Out[93]:
True
if <条件判断1>:
    <执行1>
elif <条件判断2>:
    <执行2>
elif <条件判断3>:
    <执行3>
else:
    <执行4>
In [94]:
age = float(input())
if age >= 18:
    print('adult')
elif age >= 6:
    print('teenager')
elif age > 60:
    print('old')
else:
    print('kid')
30 adult

2. 迭代

In [95]:
# 列表循环
list_1 = range(10)
for index, item in enumerate(list_1):
    print(index, item)
0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
In [96]:
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
#     sum += x
    sum = sum + x
print(sum)
55
In [24]:
sum = 0
for x in range(100):
    sum =sum +x
print(sum)
4950
In [99]:
# 字典循环
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
for k,v in d.items():
    print(k, v)
Michael 95 Bob 75 Tracy 85

函数

1.函数的调用

函数包括python自有的函数,和自定义的函数

In [100]:
#自带的函数
abs(-91)
Out[100]:
91
In [101]:
int('123')
Out[101]:
123

2.函数的定义

In [102]:
# 自己定义一个返回绝对值的函数
def my_abs(x):
    if x>=0:
        return x
    else:
        return -x

my_abs(-10)
Out[102]:
10
In [103]:
# 返回多个值
def my_abs(x):
    "返回原始值和绝对值"
    if x >= 0:
        return x, x
    else:
        return x, -x


my_abs(-100)
Out[103]:
(-100, 100)

3.函数的参数

python有四种参数传递方式:

  • 位置参数
  • 默认参数
  • 可变参数
  • 关键字参数

上面的例子都是位置参数

In [104]:
#默认参数 
def person(name, gender, age=20, city='beijing'):
    print('name:', name)
    print('gender:', gender)
    print('age:', age)
    print('city:', city)

person('tom', 'male', age=30, city='shagnhai')
name: tom gender: male age: 30 city: shagnhai
In [105]:
person('mike','male')  #age和city使用默认参数
name: mike gender: male age: 20 city: beijing

可变参数

在Python函数中,可以定义可变参数。可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个
以数学题为例子,给定一组数字a,b,c...,计算a + b + c + ...

In [108]:
def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n
    return sum
In [109]:
# 调用的时候,需要先组装出一个list或tuple
calc([1,2,3,4])
Out[109]:
10
In [110]:
# 我们把函数的参数改为可变参数
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n
    return sum
In [111]:
calc(1,2,3,4,5)
Out[111]:
15
In [114]:
#可变参数 , 在参数数量未知的情况下
def person(name, gender, age=20, city='beijing', *food):
    print('name:', name)
    print('gender:', gender)
    print('age:', age)
    print('city:', city)
    print('like-food:',','.join(food))

person('tom', 'male', 18, 'shenzhen','apple','orange', 'banana')
name: tom gender: male age: 18 city: shenzhen like-food: apple,orange,banana
In [115]:
# 已经存在一个list或tuple,可以在前面加一个*,将list或tuple元素变为可变参数
foods = ['apple','orange', 'banana']
person('tom', 'male', 18, 'shenzhen',*foods)
name: tom gender: male age: 18 city: shenzhen like-food: apple,orange,banana

关键字参数

关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

In [116]:
# 函数person除了必选参数name和age外,还接受关键字参数kw
def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)
In [120]:
person('tom',30)
name: tom age: 30 other: {}
In [117]:
person('tom',30,city='beijing')
name: tom age: 30 other: {'city': 'beijing'}
In [118]:
# 可以传入多个
person('mike',30,gender='male',job='engineer')
name: mike age: 30 other: {'gender': 'male', 'job': 'engineer'}
In [119]:
# 和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:    
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

4. 列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

要生成list[1,2,3,4,5,6,7,8],可以用list(range(1,9))

In [1]:
list(range(1,9))
Out[1]:
[1, 2, 3, 4, 5, 6, 7, 8]

如果要生成[1*1,2*2,...,10*10]的list

In [2]:
# 传统方式
L =[]
def cal_square(x):
    return x*x

for item in range(1,11):
    L.append(item*item)
In [3]:
L
Out[3]:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

可以看出来循环太繁琐,而使用列表生成式只需要一步

In [122]:
# 写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来
lc = [x * x for x in range(1, 11)]
lc
Out[122]:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:

In [123]:
[x * x for x in range(1, 11) if x % 2 == 0]
Out[123]:
[4, 16, 36, 64, 100]

还可以使用双层循环,生成全排列

In [4]:
[m+n for m in 'abc' for n in 'def']
Out[4]:
['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']

5.生成器

列表生成式一次性把所有数据都生成完,并保存到内存中,在大数据量的情况下,使用列表生成式将非常消耗内存。

python有一种更高效的方式:生成器,每次执行时动态计算,这种一边循环一边计算的机制

In [124]:
# 生成器定义
g = (x * x for x in range(10))
g
Out[124]:
<generator object <genexpr> at 0x109cdb0a0>

可以看出g没有返回所有的结果,而是一个内存地址

In [125]:
# 取值
next(g)
Out[125]:
0
In [126]:
# 循环生成器,输出结果
for item in g:
    print(item)
1 4 9 16 25 36 49 64 81

6. map函数

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。注意:返回的是生成器。

In [134]:
def f(x):
    return x * x

r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
In [135]:
r
Out[135]:
<map at 0x109ce3400>
In [136]:
next(r)
Out[136]:
1
In [137]:
list(r)
Out[137]:
[4, 9, 16, 25, 36, 49, 64, 81]
In [138]:
list(map(f,[1,2,3,4]))
Out[138]:
[1, 4, 9, 16]

7. 匿名函数

不需要显式地定义函数

In [25]:
def f1(x):
    return x*x
In [26]:
f1(5)
Out[26]:
25
In [27]:
f2 = lambda x: x*x*3
In [28]:
f2(5)
Out[28]:
75
In [29]:
#匿名函数和map
f = lambda x: x * x
list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
Out[29]:
[1, 4, 9, 16, 25, 36, 49, 64, 81]

模块

python有非常多现有的包库,可以直接使用,不用我们再次开发,重复造轮子。

  • 标准库(python官方自带)
  • 第三方库

标准库只要安装完毕,这些模块就可以立刻使用,第三方库需要手动安装,比如numpy、matplotlib...

1. 标准库

In [139]:
import math
In [140]:
import numpy as np
In [141]:
np.abs(-123)
Out[141]:
123
In [142]:
math.sqrt(123)
Out[142]:
11.090536506409418
In [143]:
math.cos(1)
Out[143]:
0.5403023058681398
In [144]:
# 查看math中的方法
dir(math)
Out[144]:
['__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 'acos',
 'acosh',
 'asin',
 'asinh',
 'atan',
 'atan2',
 'atanh',
 'ceil',
 'copysign',
 'cos',
 'cosh',
 'degrees',
 'e',
 'erf',
 'erfc',
 'exp',
 'expm1',
 'fabs',
 'factorial',
 'floor',
 'fmod',
 'frexp',
 'fsum',
 'gamma',
 'gcd',
 'hypot',
 'inf',
 'isclose',
 'isfinite',
 'isinf',
 'isnan',
 'ldexp',
 'lgamma',
 'log',
 'log10',
 'log1p',
 'log2',
 'modf',
 'nan',
 'pi',
 'pow',
 'radians',
 'sin',
 'sinh',
 'sqrt',
 'tan',
 'tanh',
 'tau',
 'trunc']

2. 第三方模块

安装方法:pip install [packagename] 或者conda install [packagename]

In [146]:
import os
os.path
Out[146]:
<module 'posixpath' from '/Users/xjy/anaconda3/lib/python3.6/posixpath.py'>
In [147]:
import tifffile
In [148]:
tifffile.__path__
Out[148]:
['/Users/xjy/anaconda3/lib/python3.6/site-packages/tifffile']
In [150]:
img = tifffile.imread('123.tiff')
In [154]:
img
Out[154]:
array([[[34266, 32160, 24615],
        [47272, 39381, 31213],
        [49258, 41020, 31149],
        ...,
        [ 4361, 10133,  3362],
        [ 4478, 11104,  4314],
        [ 8138, 13289,  6407]],

       [[30762, 28883, 21570],
        [46104, 39503, 29627],
        [56851, 50486, 38318],
        ...,
        [10864, 14684, 10975],
        [ 6658, 12742,  5455],
        [ 5217, 11347,  4123]],

       [[35240, 32221, 23219],
        [37576, 36954, 27279],
        [37576, 36954, 27279],
        ...,
        [17405, 19721, 16685],
        [13667, 16383, 10277],
        [ 6853, 11407,  5329]],

       ...,

       [[43378, 41202, 31340],
        [30022, 31735, 24171],
        [16977, 20813, 14337],
        ...,
        [22701, 25485, 20174],
        [24415, 30097, 23980],
        [24765, 30218, 23727]],

       [[16276, 22512, 13386],
        [10941, 17354,  8881],
        [10552, 18082,  8120],
        ...,
        [25427, 27245, 21950],
        [29827, 33313, 24678],
        [25232, 28519, 22838]],

       [[ 9968, 16626,  8183],
        [ 7787, 17172,  6851],
        [ 7671, 16383,  5963],
        ...,
        [23324, 26153, 21823],
        [26361, 28277, 23663],
        [23947, 26092, 21570]]], dtype=uint16)
In [155]:
img.shape
Out[155]:
(512, 512, 3)

-----------------面向对象----------------

1. 定义类

In [156]:
class Student():
    pass
In [157]:
# 实例化类
tom = Student()
type(tom)
Out[157]:
__main__.Student

2. 类的初始化

In [158]:
class Student(object):
    def __init__(self, name):
        self.name = name
        
        
tom = Student('tom')
tom.name
Out[158]:
'tom'

3. 类的方法

In [159]:
class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'
In [160]:
jake = Student('jake', 90)
jake.get_grade()
Out[160]:
'A'

-----------------文件读写----------------

1. 文本文件

In [161]:
# 读文件
f = open('point.txt', 'r', encoding='utf-8')
In [162]:
f
Out[162]:
<_io.TextIOWrapper name='point.txt' mode='r' encoding='utf-8'>
In [163]:
with open('point.txt', 'r', encoding='utf-8') as f:
    content = f.readlines()
content[0]
Out[163]:
'X,Y,fid\n'
In [164]:
content
Out[164]:
['X,Y,fid\n',
 '116.108215926863,39.7334285851988,0\n',
 '116.109210003139,39.7333587447276,1\n',
 '116.110203758974,39.7332898404484,2\n',
 '116.111200951056,39.7332734775949,3\n',
 '116.11219419024,39.733207226578,4\n',
 '116.11318709444299,39.73314179530421,5\n',
 '116.11418173517401,39.733077126743495,6\n',
 '116.115175388701,39.733023481558796,7\n',
 '116.116122015996,39.7280722607491,8\n',
 '116.11510885117501,39.727173869159,9\n',
 '116.11417471340599,39.727405480615,10\n',
 '116.13308786381701,39.7154546039897,11\n',
 '116.134084018368,39.7154946947937,12\n',
 '116.13507667496401,39.715547079319,13\n',
 '116.136069307341,39.7155995350501,14\n',
 '116.133080229079,39.739589671489604,15']
In [165]:
#写文件
with open('out_file.csv', 'w') as f:
    for item in content:
        f.write(item)

2. 图像文件

In [167]:
from PIL import Image
img = Image.open('image.jpg')
print(img.size)
img
(512, 512)
Out[167]: