Skip to content

Commit ef30194

Browse files
authored
Add files via upload
1 parent 086aa5d commit ef30194

File tree

2 files changed

+330
-0
lines changed

2 files changed

+330
-0
lines changed

charpter19_SVD/louwill.jpg

459 KB
Loading

charpter19_SVD/svd.ipynb

Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"#### SVD"
8+
]
9+
},
10+
{
11+
"cell_type": "code",
12+
"execution_count": 1,
13+
"metadata": {},
14+
"outputs": [],
15+
"source": [
16+
"import numpy as np"
17+
]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": 2,
22+
"metadata": {},
23+
"outputs": [
24+
{
25+
"data": {
26+
"text/plain": [
27+
"array([[0, 1],\n",
28+
" [1, 1],\n",
29+
" [1, 0]])"
30+
]
31+
},
32+
"execution_count": 2,
33+
"metadata": {},
34+
"output_type": "execute_result"
35+
}
36+
],
37+
"source": [
38+
"A = np.array([[0,1],[1,1],[1,0]])\n",
39+
"A"
40+
]
41+
},
42+
{
43+
"cell_type": "code",
44+
"execution_count": 3,
45+
"metadata": {},
46+
"outputs": [
47+
{
48+
"name": "stdout",
49+
"output_type": "stream",
50+
"text": [
51+
"(3, 3) (2,) (2, 2)\n"
52+
]
53+
}
54+
],
55+
"source": [
56+
"u, s, vt = np.linalg.svd(A, full_matrices=True)\n",
57+
"print(u.shape, s.shape, vt.shape)"
58+
]
59+
},
60+
{
61+
"cell_type": "code",
62+
"execution_count": 4,
63+
"metadata": {},
64+
"outputs": [
65+
{
66+
"data": {
67+
"text/plain": [
68+
"array([[-4.08248290e-01, 7.07106781e-01, 5.77350269e-01],\n",
69+
" [-8.16496581e-01, 5.55111512e-17, -5.77350269e-01],\n",
70+
" [-4.08248290e-01, -7.07106781e-01, 5.77350269e-01]])"
71+
]
72+
},
73+
"execution_count": 4,
74+
"metadata": {},
75+
"output_type": "execute_result"
76+
}
77+
],
78+
"source": [
79+
"u"
80+
]
81+
},
82+
{
83+
"cell_type": "code",
84+
"execution_count": 5,
85+
"metadata": {},
86+
"outputs": [
87+
{
88+
"data": {
89+
"text/plain": [
90+
"array([1.73205081, 1. ])"
91+
]
92+
},
93+
"execution_count": 5,
94+
"metadata": {},
95+
"output_type": "execute_result"
96+
}
97+
],
98+
"source": [
99+
"s"
100+
]
101+
},
102+
{
103+
"cell_type": "code",
104+
"execution_count": 6,
105+
"metadata": {},
106+
"outputs": [
107+
{
108+
"data": {
109+
"text/plain": [
110+
"array([[-0.70710678, -0.70710678],\n",
111+
" [-0.70710678, 0.70710678]])"
112+
]
113+
},
114+
"execution_count": 6,
115+
"metadata": {},
116+
"output_type": "execute_result"
117+
}
118+
],
119+
"source": [
120+
"vt.T"
121+
]
122+
},
123+
{
124+
"cell_type": "code",
125+
"execution_count": 8,
126+
"metadata": {},
127+
"outputs": [
128+
{
129+
"data": {
130+
"text/plain": [
131+
"True"
132+
]
133+
},
134+
"execution_count": 8,
135+
"metadata": {},
136+
"output_type": "execute_result"
137+
}
138+
],
139+
"source": [
140+
"np.allclose(A, np.dot(u[:,:2]*s, vt))"
141+
]
142+
},
143+
{
144+
"cell_type": "code",
145+
"execution_count": 10,
146+
"metadata": {},
147+
"outputs": [
148+
{
149+
"data": {
150+
"text/plain": [
151+
"array([[ 1.11022302e-16, 1.00000000e+00],\n",
152+
" [ 1.00000000e+00, 1.00000000e+00],\n",
153+
" [ 1.00000000e+00, -3.33066907e-16]])"
154+
]
155+
},
156+
"execution_count": 10,
157+
"metadata": {},
158+
"output_type": "execute_result"
159+
}
160+
],
161+
"source": [
162+
"np.dot(u[:,:2]*s, vt)"
163+
]
164+
},
165+
{
166+
"cell_type": "code",
167+
"execution_count": 17,
168+
"metadata": {},
169+
"outputs": [
170+
{
171+
"data": {
172+
"text/plain": [
173+
"array([[1.73205081, 0. ],\n",
174+
" [0. , 1. ],\n",
175+
" [0. , 0. ]])"
176+
]
177+
},
178+
"execution_count": 17,
179+
"metadata": {},
180+
"output_type": "execute_result"
181+
}
182+
],
183+
"source": [
184+
"s_ = np.zeros((3,2))\n",
185+
"for i in range(2):\n",
186+
" s_[i][i] = s[i]\n",
187+
"\n",
188+
"s_"
189+
]
190+
},
191+
{
192+
"cell_type": "code",
193+
"execution_count": 22,
194+
"metadata": {},
195+
"outputs": [
196+
{
197+
"data": {
198+
"text/plain": [
199+
"array([[ 1.11022302e-16, 1.00000000e+00],\n",
200+
" [ 1.00000000e+00, 1.00000000e+00],\n",
201+
" [ 1.00000000e+00, -3.33066907e-16]])"
202+
]
203+
},
204+
"execution_count": 22,
205+
"metadata": {},
206+
"output_type": "execute_result"
207+
}
208+
],
209+
"source": [
210+
"np.dot(np.dot(u, s_), vt)"
211+
]
212+
},
213+
{
214+
"cell_type": "code",
215+
"execution_count": 7,
216+
"metadata": {},
217+
"outputs": [
218+
{
219+
"name": "stderr",
220+
"output_type": "stream",
221+
"text": [
222+
"100%|██████████████████████████████████████████████████████████████████████████████████| 50/50 [02:11<00:00, 2.63s/it]\n"
223+
]
224+
}
225+
],
226+
"source": [
227+
"import numpy as np\n",
228+
"import os\n",
229+
"from PIL import Image\n",
230+
"from tqdm import tqdm\n",
231+
"\n",
232+
"# 定义恢复函数,由分解后的矩阵恢复到原矩阵\n",
233+
"def restore(u, s, v, K): \n",
234+
" '''\n",
235+
" u:左奇异矩阵\n",
236+
" v:右奇异矩阵\n",
237+
" s:奇异值矩阵\n",
238+
" K:奇异值个数\n",
239+
" '''\n",
240+
" m, n = len(u), len(v[0])\n",
241+
" a = np.zeros((m, n))\n",
242+
" for k in range(K):\n",
243+
" uk = u[:, k].reshape(m, 1)\n",
244+
" vk = v[k].reshape(1, n)\n",
245+
" # 前k个奇异值的加总\n",
246+
" a += s[k] * np.dot(uk, vk) \n",
247+
" a = a.clip(0, 255)\n",
248+
" return np.rint(a).astype('uint8')\n",
249+
"\n",
250+
"A = np.array(Image.open(\"./louwill.jpg\", 'r'))\n",
251+
"# 对RGB图像进行奇异值分解\n",
252+
"u_r, s_r, v_r = np.linalg.svd(A[:, :, 0]) \n",
253+
"u_g, s_g, v_g = np.linalg.svd(A[:, :, 1])\n",
254+
"u_b, s_b, v_b = np.linalg.svd(A[:, :, 2])\n",
255+
"\n",
256+
"# 使用前50个奇异值\n",
257+
"K = 50 \n",
258+
"output_path = r'./svd_pic'\n",
259+
"# \n",
260+
"for k in tqdm(range(1, K+1)):\n",
261+
" R = restore(u_r, s_r, v_r, k)\n",
262+
" G = restore(u_g, s_g, v_g, k)\n",
263+
" B = restore(u_b, s_b, v_b, k)\n",
264+
" I = np.stack((R, G, B), axis=2) \n",
265+
" Image.fromarray(I).save('%s\\\\svd_%d.jpg' % (output_path, k))"
266+
]
267+
},
268+
{
269+
"cell_type": "code",
270+
"execution_count": 4,
271+
"metadata": {},
272+
"outputs": [
273+
{
274+
"data": {
275+
"text/plain": [
276+
"(959, 959, 3)"
277+
]
278+
},
279+
"execution_count": 4,
280+
"metadata": {},
281+
"output_type": "execute_result"
282+
}
283+
],
284+
"source": [
285+
"A.shape"
286+
]
287+
},
288+
{
289+
"cell_type": "code",
290+
"execution_count": null,
291+
"metadata": {},
292+
"outputs": [],
293+
"source": []
294+
}
295+
],
296+
"metadata": {
297+
"kernelspec": {
298+
"display_name": "Python 3",
299+
"language": "python",
300+
"name": "python3"
301+
},
302+
"language_info": {
303+
"codemirror_mode": {
304+
"name": "ipython",
305+
"version": 3
306+
},
307+
"file_extension": ".py",
308+
"mimetype": "text/x-python",
309+
"name": "python",
310+
"nbconvert_exporter": "python",
311+
"pygments_lexer": "ipython3",
312+
"version": "3.7.3"
313+
},
314+
"toc": {
315+
"base_numbering": 1,
316+
"nav_menu": {},
317+
"number_sections": true,
318+
"sideBar": true,
319+
"skip_h1_title": false,
320+
"title_cell": "Table of Contents",
321+
"title_sidebar": "Contents",
322+
"toc_cell": false,
323+
"toc_position": {},
324+
"toc_section_display": true,
325+
"toc_window_display": false
326+
}
327+
},
328+
"nbformat": 4,
329+
"nbformat_minor": 2
330+
}

0 commit comments

Comments
 (0)