নম্পি ডট () এবং পাইথন 3.5+ ম্যাট্রিক্স গুণন @ এর মধ্যে পার্থক্য


119

আমি সম্প্রতি পাইথন 3.5 তে চলে এসেছি এবং লক্ষ্য করেছি যে নতুন ম্যাট্রিক্স গুণিত অপারেটর (@) কখনও কখনও নিম্পি ডট অপারেটর থেকে আলাদা আচরণ করে । উদাহরণস্বরূপ, 3 ডি অ্যারেগুলির জন্য:

import numpy as np

a = np.random.rand(8,13,13)
b = np.random.rand(8,13,13)
c = a @ b  # Python 3.5+
d = np.dot(a, b)

@অপারেটর আকৃতি একটি বিন্যাস দেখায়:

c.shape
(8, 13, 13)

যখন np.dot()ফাংশন আয়:

d.shape
(8, 13, 8, 13)

আমি কীভাবে একই ফলাফলটিকে নামী বিন্দু দিয়ে পুনরুত্পাদন করতে পারি? অন্য কোন উল্লেখযোগ্য পার্থক্য আছে?


5
আপনি ফলাফলটি বিন্দু থেকে পেতে পারেন না। আমি মনে করি লোকেরা সাধারণত সম্মত হয় যে উচ্চ মাত্রার ইনপুটগুলি ডট পরিচালনা করা ভুল নকশার সিদ্ধান্ত ছিল।
ব্যবহারকারী 2357112 মনিকা

বছরখানেক matmulআগে তারা এই কার্যক্রমটি বাস্তবায়ন করেনি কেন ? @যেমন একটি ইনফিক্স অপারেটর নতুন, তবে ফাংশনটি ঠিক এটি ছাড়াও কাজ করে।
এইচপলজ

উত্তর:


140

@অপারেটর অ্যারে এর কল __matmul__পদ্ধতি, না dot। এই পদ্ধতিটি ফাংশন হিসাবে এপিআইতে উপস্থিত রয়েছে np.matmul

>>> a = np.random.rand(8,13,13)
>>> b = np.random.rand(8,13,13)
>>> np.matmul(a, b).shape
(8, 13, 13)

ডকুমেন্টেশন থেকে:

matmuldotদুটি গুরুত্বপূর্ণ উপায়ে পৃথক ।

  • স্কেলারদের দ্বারা গুণ করা অনুমোদিত নয়।
  • ম্যাট্রিকের স্ট্যাকগুলি একসাথে সম্প্রচারিত হয় যেন ম্যাট্রিকগুলি উপাদান ছিল।

শেষ পয়েন্টটি পরিষ্কার করে দেয় যে 3 ডি (বা উচ্চতর মাত্রিক) অ্যারে পাস করার সময় dotএবং matmulপদ্ধতিগুলি আলাদাভাবে আচরণ করে। ডকুমেন্টেশন থেকে আরও কিছু উদ্ধৃত:

এর জন্য matmul:

যদি কোনও যুক্তি এনডি, এন> 2 হয় তবে এটি শেষ দুটি সূচকে থাকা ম্যাট্রিকের স্ট্যাক হিসাবে বিবেচিত হবে এবং সে অনুযায়ী সম্প্রচারিত হবে।

এর জন্য np.dot:

২-ডি অ্যারেগুলির জন্য এটি ম্যাট্রিক্স গুণণের সমতুল্য এবং 1-ডি অ্যারেগুলির জন্য ভেক্টরগুলির অভ্যন্তরীণ পণ্য (জটিল সংমিশ্রণ ছাড়াই)। এন মাত্রা জন্য এটি একটি এর শেষ অক্ষ এবং খ এর দ্বিতীয় থেকে শেষের উপরের যোগফল


13
এখানে বিভ্রান্তি সম্ভবত রিলিজ নোটগুলির কারণে, যা উদাহরণস্বরূপের কোডের মধ্যে নিম্পির বিন্দু () ফাংশনের সাথে সরাসরি "@" চিহ্নকে সমান করে।
অ্যালেক্স কে

12

@ এ্যাসক্রির উত্তরটি ব্যাখ্যা করে যে কীভাবে dotএবং matmul( আ@ প্রতীক ) পৃথক হয়। একটি সাধারণ উদাহরণ দেখে, একটি স্পষ্টভাবে দেখতে পাবে যে 'ম্যাট্রিক্সের স্ট্যাকস' বা টেনসরগুলিতে অপারেট করার সময় দু'জন কীভাবে আলাদা আচরণ করে।

পার্থক্যগুলি স্পষ্ট করতে 4x4 অ্যারে নিন এবং 3x4x2 'ম্যাট্রিকের স্ট্যাক' বা টেনসর দিয়ে dotপণ্য এবং matmulপণ্যটি ফিরিয়ে দিন।

import numpy as np
fourbyfour = np.array([
                       [1,2,3,4],
                       [3,2,1,4],
                       [5,4,6,7],
                       [11,12,13,14]
                      ])


threebyfourbytwo = np.array([
                             [[2,3],[11,9],[32,21],[28,17]],
                             [[2,3],[1,9],[3,21],[28,7]],
                             [[2,3],[1,9],[3,21],[28,7]],
                            ])

print('4x4*3x4x2 dot:\n {}\n'.format(np.dot(fourbyfour,twobyfourbythree)))
print('4x4*3x4x2 matmul:\n {}\n'.format(np.matmul(fourbyfour,twobyfourbythree)))

প্রতিটি অপারেশনের পণ্যগুলি নীচে উপস্থিত হয়। বিন্দুর পণ্যটি কেমন তা লক্ষ্য করুন,

... a এর শেষ অক্ষের সাথে একটি যোগফল এবং খ-এর দ্বিতীয় থেকে শেষের দিকে

এবং ম্যাট্রিক্স পণ্যটি কীভাবে একসাথে ম্যাট্রিক্স সম্প্রচারের মাধ্যমে গঠিত হয়।

4x4*3x4x2 dot:
 [[[232 152]
  [125 112]
  [125 112]]

 [[172 116]
  [123  76]
  [123  76]]

 [[442 296]
  [228 226]
  [228 226]]

 [[962 652]
  [465 512]
  [465 512]]]

4x4*3x4x2 matmul:
 [[[232 152]
  [172 116]
  [442 296]
  [962 652]]

 [[125 112]
  [123  76]
  [228 226]
  [465 512]]

 [[125 112]
  [123  76]
  [228 226]
  [465 512]]]

2
বিন্দু (ক, খ) [আমি, জে, কে, এম] = যোগ (ক [আমি, জে ,:] * খ [কে,:, মি]) ------- যেমন নথিপত্র বলেছেন: এটি একটি : একটি শেষ অক্ষ এবং খ দ্বিতীয় টু গত অক্ষের সমষ্টি পণ্য
রোনাক আগরওয়াল

ভাল ধরা তবে এটি একটি 3x4x2। ম্যাট্রিক্স তৈরির আর একটি উপায় a = np.arange(24).reshape(3, 4, 2)হ'ল এটি 3x4x2 মাত্রা সহ একটি অ্যারে তৈরি করবে।
নাথান

8

কেবল এফওয়াইআই, @এবং এর নির্লজ্জ সমতুল্য dotএবং matmulএগুলি মোটামুটি সমান দ্রুত। ( আমার একটি প্রকল্প পারফ্লট্লট দিয়ে প্লট তৈরি করা হয়েছে ))

এখানে চিত্র বর্ণনা লিখুন

প্লটটি পুনরুত্পাদন করার কোড:

import perfplot
import numpy


def setup(n):
    A = numpy.random.rand(n, n)
    x = numpy.random.rand(n)
    return A, x


def at(data):
    A, x = data
    return A @ x


def numpy_dot(data):
    A, x = data
    return numpy.dot(A, x)


def numpy_matmul(data):
    A, x = data
    return numpy.matmul(A, x)


perfplot.show(
    setup=setup,
    kernels=[at, numpy_dot, numpy_matmul],
    n_range=[2 ** k for k in range(12)],
    logx=True,
    logy=True,
)

7

গণিতে আমার মনে হয়, বিন্দু বিন্দুটি আরও বোধগম্য

বিন্দু (ক, খ) _ {আই, জে, কে, এ, বি, সি} =সূত্র

যেহেতু এটি বিন্দু পণ্য দেয় যখন a এবং b ভেক্টর হয় বা ম্যাট্রিক্সের গুণ যখন a এবং b ম্যাট্রিক হয়


নম্পিতে ম্যাটমুল অপারেশন হিসাবে এটি বিন্দু ফলাফলের অংশগুলি নিয়ে গঠিত এবং এটি হিসাবে সংজ্ঞায়িত করা যায়

> মাতমুল (ক, খ) _ {আই, জে, কে, সি} =সূত্র

সুতরাং, আপনি দেখতে পাচ্ছেন যে ম্যাটমুল (ক, খ) একটি ছোট আকারের সাথে একটি অ্যারে প্রদান করে, যার মেমরির পরিমাণ কম থাকে এবং অ্যাপ্লিকেশনগুলিতে আরও জ্ঞান লাভ করে। বিশেষত, সম্প্রচারের সাথে সম্মিলন করে আপনি পেতে পারেন

মাতমুল (ক, খ) _ {আই, জে, কে, এল} =সূত্র

উদাহরণ স্বরূপ.


উপরের দুটি সংজ্ঞা থেকে, আপনি এই দুটি অপারেশন ব্যবহার করার প্রয়োজনীয়তা দেখতে পাবেন। ধরুন a.shape = (s1, s2, s3, s4) এবং b. Shape = (t1, t2, t3, t4)

  • বিন্দু (ক, খ) ব্যবহার করতে আপনার প্রয়োজন

    1. t3 = এস 4 ;
  • ম্যাটমুল (ক, খ) ব্যবহার করতে আপনার প্রয়োজন

    1. T3 = S4
    2. t2 = s2 , বা t2 এবং s2 এর মধ্যে 1 হয়
    3. টি 1 = এস 1 , বা টি 1 এবং এস 1 এর 1 হ'ল

নিজেকে বোঝাতে নীচের কোডটির টুকরোটি ব্যবহার করুন।

কোড নমুনা

import numpy as np
for it in xrange(10000):
    a = np.random.rand(5,6,2,4)
    b = np.random.rand(6,4,3)
    c = np.matmul(a,b)
    d = np.dot(a,b)
    #print 'c shape: ', c.shape,'d shape:', d.shape

    for i in range(5):
        for j in range(6):
            for k in range(2):
                for l in range(3):
                    if not c[i,j,k,l] == d[i,j,k,j,l]:
                        print it,i,j,k,l,c[i,j,k,l]==d[i,j,k,j,l] #you will not see them

np.matmulএছাড়াও ভেক্টরগুলিতে ডট পণ্য এবং ম্যাট্রিক্সে ম্যাট্রিক্স পণ্য দেয়।
সুবহানিল লাহিড়ী

2

np.einsumসূচকগুলি কীভাবে প্রক্ষেপণ করা হয় তা দেখানোর জন্য এখানে একটি তুলনা করা হয়েছে

np.allclose(np.einsum('ijk,ijk->ijk', a,b), a*b)        # True 
np.allclose(np.einsum('ijk,ikl->ijl', a,b), a@b)        # True
np.allclose(np.einsum('ijk,lkm->ijlm',a,b), a.dot(b))   # True

0

ম্যাটমুল এবং ডটের সাথে আমার অভিজ্ঞতা

ম্যাটমুল ব্যবহার করার চেষ্টা করার সময় আমি ক্রমাগত "ভ্যালুয়েরর: পাস হওয়া মানগুলির আকার (200, 1), সূচকগুলি বোঝায় (200, 3)" পেয়ে যাচ্ছিলাম। আমি দ্রুত কাজ করতে চেয়েছি এবং একই কার্যকারিতা সরবরাহ করতে ডট পেয়েছি। আমি ডট ব্যবহার করে কোনও ত্রুটি পাই না। আমি সঠিক উত্তর পেতে

ম্যাথামুলের সাথে

X.shape
>>>(200, 3)

type(X)

>>>pandas.core.frame.DataFrame

w

>>>array([0.37454012, 0.95071431, 0.73199394])

YY = np.matmul(X,w)

>>>  ValueError: Shape of passed values is (200, 1), indices imply (200, 3)"

ডট সহ

YY = np.dot(X,w)
# no error message
YY
>>>array([ 2.59206877,  1.06842193,  2.18533396,  2.11366346,  0.28505879, 

YY.shape

>>> (200, )
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.